flare_splash_screen
flare_splash_screen copied to clipboard
setState() called after dispose(): _FlareLoadingState#...
Hi, it's me again, your favourite source of unwanted bug reports.
I'll start off with the error message.
E/flutter (14134): [ERROR:flutter/shell/common/shell.cc(209)] Dart Error: Unhandled exception:
E/flutter (14134): setState() called after dispose(): _FlareLoadingState#27075(lifecycle state: defunct, not mounted)
E/flutter (14134): This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback.
E/flutter (14134): The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.
E/flutter (14134): This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().
E/flutter (14134): #0 State.setState.<anonymous closure> (package:flutter/src/widgets/framework.dart:1204:9)
E/flutter (14134): #1 State.setState (package:flutter/src/widgets/framework.dart:1239:6)
E/flutter (14134): #2 _FlareLoadingState._processCallback (package:flare_loading/flare_loading.dart:104:7)
E/flutter (14134): <asynchronous suspension>
E/flutter (14134): #3 _FlareLoadingState.initState (package:flare_loading/flare_loading.dart:56:5)
Now this has proven a really pesky one to debug because it doesn't always occur. So it's a time-sensitive issue, a race condition. I included a bit of stacktrace above that points to flare_loading
and indeed, it does set setState
. I have a feeling my until
function finishes before my animation finishes. My onSuccess
navigates elsewhere so I assume this removes the widget from the tree or something, which meshes with the verbose error I get. Still, I haven't been able to figure it out exactly.
I thought I'd report it here in case any of things rings a bell or the solution is obvious.
Having seen this happen quite a few times now, I can confirm it happens when the enclosing build
gets called again quickly after the first call. Why this happens I still cannot fathom. It seems pretty random -- Widget.build
gets called somewhere between 1 (happy days) and 3 times.
I have worked around it by being clever with the key
parameter, only changing it when I do want a new SplashScreent to be constructed, which isn't before onError
is called in my case.
Ok strange one ^^ never got it because I don't play with key or rebuild for my splashscreen ^^ I'll try to take a look when I have time, but if someone can make a PR to fix that it would be welcome :D
I'll keep an eye on it and see if I can fix it.
Thing is, I got the error even without rebuilding. Because somehow, something decides to call build
on my Widget twice in quick succession. Sometimes. I looked up why and Flutter docs simply state that build
should be a pure function without side-effects because if the parent gets resized or something, build might get called again. This widget does live inside a Scaffold I just realised so maybe it's got something to do with that resizing.. No idea yet.
So the error is not in this repo but in flare_loading, which is a statefulWidget, so I think before each setState a check should be made to see if widget is still mounted
, you can try that manually as you manage to sometime reproduce it on your side see if it fix the problem