Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AnimationContoller in Tile is not being disposed #595

Closed
kuhnroyal opened this issue Apr 20, 2020 · 11 comments
Closed

AnimationContoller in Tile is not being disposed #595

kuhnroyal opened this issue Apr 20, 2020 · 11 comments

Comments

@kuhnroyal
Copy link
Contributor

A call to animationController?.dispose() is missing after line https://github.com/johnpryan/flutter_map/blob/master/lib/src/layer/tile_layer.dart#L951

This fails on Flutter 1.17.0-dev.3.1 with the following error:

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following assertion was thrown while finalizing the widget tree:
_TileLayerState#7cdb2(tickers: tracking 3 tickers) was disposed with an active Ticker.

_TileLayerState created a Ticker via its TickerProviderStateMixin, but at the time dispose() was called on the mixin, that Ticker was still active. All Tickers must be disposed before calling super.dispose().

Tickers used by AnimationControllers should be disposed by calling dispose() on the AnimationController itself. Otherwise, the ticker will leak.

The offending ticker was: _WidgetTicker(created by _TileLayerState#7cdb2(tickers: tracking 0 tickers))
The stack trace when the _WidgetTicker was actually created was:
#0      new Ticker.<anonymous closure> (package:flutter/src/scheduler/ticker.dart:66:40)
#1      new Ticker (package:flutter/src/scheduler/ticker.dart:68:6)
#2      new _WidgetTicker (package:flutter/src/widgets/ticker_provider.dart:271:80)
#3      TickerProviderStateMixin.createTicker (package:flutter/src/widgets/ticker_provider.dart:202:34)
#4      new AnimationController (package:flutter/src/animation/animation_controller.dart:247:21)
#5      Tile.startFadeInAnimation (package:flutter_map/src/layer/tile_layer.dart:957:27)
#6      _TileLayerState._tileReady (package:flutter_map/src/layer/tile_layer.dart:838:12)
#7      Tile._tileOnLoad (package:flutter_map/src/layer/tile_layer.dart:972:16)
#8      ImageStreamCompleter.setImage (package:flutter/src/painting/image_stream.dart:437:25)
#9      MultiFrameImageStreamCompleter._emitFrame (package:flutter/src/painting/image_stream.dart:739:5)
#10     MultiFrameImageStreamCompleter._decodeNextFrameAndSchedule (package:flutter/src/painting/image_stream.dart:724:7)
<asynchronous suspension>
#11     MultiFrameImageStreamCompleter._handleCodecReady (package:flutter/src/painting/image_stream.dart:674:7)
#23     CachedNetworkImageProvider._loadAsync (package:cached_network_image/src/cached_network_image_provider.dart)
<asynchronous suspension>
#24     CachedNetworkImageProvider.load (package:cached_network_image/src/cached_network_image_provider.dart:45:14)
#25     ImageProvider.resolveStreamForKey.<anonymous closure> (package:flutter/src/painting/image_provider.dart:501:13)
#26     ImageCache.putIfAbsent (package:flutter/src/painting/image_cache.dart:359:22)
#27     ImageProvider.resolveStreamForKey (package:flutter/src/painting/image_provider.dart:499:80)
#28     ImageProvider.resolve.<anonymous closure> (package:flutter/src/painting/image_provider.dart:330:9)
#29     ImageProvider._createErrorHandlerAndKey.<anonymous closure>.<anonymous closure> (package:flutter/src/painting/image_provider.dart:460:26)
#30     SynchronousFuture.then (package:flutter/src/foundation/synchronous_future.dart:41:29)
#31     ImageProvider._createErrorHandlerAndKey.<anonymous closure> (package:flutter/src/painting/image_provider.dart:457:11)
#35     ImageProvider._createErrorHandlerAndKey (package:flutter/src/painting/image_provider.dart:449:16)
#36     ImageProvider.resolve (package:flutter/src/painting/image_provider.dart:327:5)
#37     new Tile (package:flutter_map/src/layer/tile_layer.dart:933:36)
#38     _TileLayerState._addTile (package:flutter_map/src/layer/tile_layer.dart:808:31)
#39     _TileLayerState._update (package:flutter_map/src/layer/tile_layer.dart:762:7)
#40     _TileLayerState._setView (package:flutter_map/src/layer/tile_layer.dart:603:7)
#41     _TileLayerState._resetView (package:flutter_map/src/layer/tile_layer.dart:573:5)
#42     _TileLayerState.initState (package:flutter_map/src/layer/tile_layer.dart:316:5)
#43     StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4640:58)
#44     ComponentElement.mount (package:flutter/src/widgets/framework.dart:4476:5)
#45     Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14)
#46     MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5947:32)

I have not noticed this error before with an older Flutter version and since there seem to be no changes in the TileLayer that can cause this I assume this is a new check in Flutter.

kuhnroyal added a commit to kuhnroyal/flutter_map that referenced this issue Apr 20, 2020
Correctly dispose TileLayer and Tiles in the order required by the TickerProviderStateMixin. The AnimationController in the tiles was not being disposed at all. After this change `_pruneTiles` sometimes gets called after the widget is already disposed - added a mounted check to prevent this.
@kuhnroyal
Copy link
Contributor Author

Nevermind the Flutter version, this was introduced in d4aefae

@kuhnroyal
Copy link
Contributor Author

@maRci002 Can you review my change and see if that makes sense.

@olofho
Copy link

olofho commented Apr 20, 2020

I have this issue as well

I/flutter ( 5167): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 5167): The following assertion was thrown while finalizing the widget tree:
I/flutter ( 5167): _TileLayerState#590a8(tickers: tracking 48 tickers) was disposed with an active Ticker.
I/flutter ( 5167): _TileLayerState created a Ticker via its TickerProviderStateMixin, but at the time dispose() was
I/flutter ( 5167): called on the mixin, that Ticker was still active. All Tickers must be disposed before calling
I/flutter ( 5167): super.dispose().
I/flutter ( 5167): Tickers used by AnimationControllers should be disposed by calling dispose() on the
I/flutter ( 5167): AnimationController itself. Otherwise, the ticker will leak.
I/flutter ( 5167): The offending ticker was:
I/flutter ( 5167):   _WidgetTicker(created by _TileLayerState#590a8(tickers: tracking 47 tickers))
I/flutter ( 5167):   The stack trace when the _WidgetTicker was actually created was:
I/flutter ( 5167):   #0      new Ticker.<anonymous closure> (package:flutter/src/scheduler/ticker.dart:66:40)
I/flutter ( 5167):   #1      new Ticker (package:flutter/src/scheduler/ticker.dart:68:6)
I/flutter ( 5167):   #2      new _WidgetTicker (package:flutter/src/widgets/ticker_provider.dart:237:80)
I/flutter ( 5167):   #3      TickerProviderStateMixin.createTicker
I/flutter ( 5167):   (package:flutter/src/widgets/ticker_provider.dart:168:34)
I/flutter ( 5167):   #4      new AnimationController (package:flutter/src/animation/animation_controller.dart:245:21)
I/flutter ( 5167):   #5      Tile.startFadeInAnimation (package:flutter_map/src/layer/tile_layer.dart:956:27)
I/flutter ( 5167):   #6      _TileLayerState._tileReady (package:flutter_map/src/layer/tile_layer.dart:838:12)
I/flutter ( 5167):   #7      Tile._tileOnLoad (package:flutter_map/src/layer/tile_layer.dart:971:7)
I/flutter ( 5167):   #8      ImageStreamCompleter.setImage (package:flutter/src/painting/image_stream.dart:407:18)
I/flutter ( 5167):   #9      MultiFrameImageStreamCompleter._emitFrame
I/flutter ( 5167):   (package:flutter/src/painting/image_stream.dart:709:5)
I/flutter ( 5167):   #10     MultiFrameImageStreamCompleter._decodeNextFrameAndSchedule
I/flutter ( 5167):   (package:flutter/src/painting/image_stream.dart:694:7)
I/flutter ( 5167):   <asynchronous suspension>
I/flutter ( 5167):   #11     MultiFrameImageStreamCompleter._handleCodecReady
I/flutter ( 5167):   (package:flutter/src/painting/image_stream.dart:644:7)
I/flutter ( 5167):   #22     CachedNetworkImageProvider._loadAsyncFromFile
I/flutter ( 5167):   (package:cached_network_image/src/cached_network_image_provider.dart)
I/flutter ( 5167):   <asynchronous suspension>
I/flutter ( 5167):   #23     CachedNetworkImageProvider._loadAsync
I/flutter ( 5167):   (package:cached_network_image/src/cached_network_image_provider.dart:63:12)
I/flutter ( 5167):   <asynchronous suspension>
I/flutter ( 5167):   #24     CachedNetworkImageProvider.load
I/flutter ( 5167):   (package:cached_network_image/src/cached_network_image_provider.dart:44:14)
I/flutter ( 5167):   #25     ImageProvider.resolve.<anonymous closure>.<anonymous closure>.<anonymous closure>
I/flutter ( 5167):   (package:flutter/src/painting/image_provider.dart:327:17)
I/flutter ( 5167):   #26     ImageCache.putIfAbsent (package:flutter/src/painting/image_cache.dart:160:22)
I/flutter ( 5167):   #27     ImageProvider.resolve.<anonymous closure>.<anonymous closure>
I/flutter ( 5167):   (package:flutter/src/painting/image_provider.dart:325:84)
I/flutter ( 5167):   #28     SynchronousFuture.then (package:flutter/src/foundation/synchronous_future.dart:38:29)
I/flutter ( 5167):   #29     ImageProvider.resolve.<anonymous closure>
I/flutter ( 5167):   (package:flutter/src/painting/image_provider.dart:323:11)
I/flutter ( 5167):   #33     ImageProvider.resolve (package:flutter/src/painting/image_provider.dart:315:16)
I/flutter ( 5167):   #34     new Tile (package:flutter_map/src/layer/tile_layer.dart:933:36)
I/flutter ( 5167):   #35     _TileLayerState._addTile (package:flutter_map/src/layer/tile_layer.dart:808:31)
I/flutter ( 5167):   #36     _TileLayerState._update (package:flutter_map/src/layer/tile_layer.dart:762:7)
I/flutter ( 5167):   #37     _TileLayerState._setView (package:flutter_map/src/layer/tile_layer.dart:603:7)
I/flutter ( 5167):   #38     _TileLayerState._handleMove.<anonymous closure>
I/flutter ( 5167):   (package:flutter_map/src/layer/tile_layer.dart:680:11)
I/flutter ( 5167):   #39     State.setState (package:flutter/src/widgets/framework.dart:1148:30)
I/flutter ( 5167):   #40     _TileLayerState._handleMove (package:flutter_map/src/layer/tile_layer.dart:677:7)
I/flutter ( 5167):   #41     _TileLayerState.initState.<anonymous closure>
I/flutter ( 5167):   (package:flutter_map/src/layer/tile_layer.dart:318:44)
I/flutter ( 5167):   (elided 30 frames from package dart:async and package dart:async-patch)

@maRci002
Copy link
Contributor

I haven't seen this error, however when I made #584 PR then I saw dispose() was called too early so I patched it however #596 seems even stronger guard because it protects setState call when Tile is ready and it disposes animationController appropriately.
https://github.com/johnpryan/flutter_map/pull/584/files#diff-d0fc1fe821e34169c8068a76a40415f3R375

@kuhnroyal I think your patch seems fine.

@salvatore373
Copy link

Can this issue be considered fixed?

@kuhnroyal
Copy link
Contributor Author

@salvatore373 Not unless my PR gets merged. Currently this project seems inactive.

@salvatore373
Copy link

@kuhnroyal Are you talking about the a00355b commit?

@kuhnroyal
Copy link
Contributor Author

Yes

@z-tc
Copy link

z-tc commented Oct 1, 2020

what is the status of this issue? I still have the same problem with the latest library...

@maRci002
Copy link
Contributor

maRci002 commented Oct 1, 2020

@z-tc #596 was merged, so this shouldn't happen.

@PaRaDoX50
Copy link

Still experiencing the same issue on 0.13.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants