flare_splash_screen icon indicating copy to clipboard operation
flare_splash_screen copied to clipboard

setState() called after dispose(): _FlareLoadingState#...

Open rubenvereecken opened this issue 4 years ago • 4 comments

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.

rubenvereecken avatar Aug 17 '20 17:08 rubenvereecken

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.

rubenvereecken avatar Aug 19 '20 08:08 rubenvereecken

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

jaumard avatar Aug 19 '20 14:08 jaumard

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.

rubenvereecken avatar Aug 19 '20 16:08 rubenvereecken

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

jaumard avatar Aug 19 '20 17:08 jaumard