Skip to content

dispose() of Stateful widgets is not called when the App is exited by pressing the backbutton #40940

Open

Description

@HQiang

Why are some widget state dispose() executed when the page is closed, some widget states don't execute dispose, it's really annoying, I want to cry, and the resource release is a problem.

Activity

  1. dblokhin commented on Sep 20, 2019

    @dblokhin

    It would be nice if you attach some problem code.

  2. HQiang commented on Sep 20, 2019

    @HQiang
    Author

    Because there is a lot of code, I can't paste it. I probably tested it myself. This happens when the current page is the last page of the application. Clicking Back will exit the application. At this time, the Widget and the Widget are included. The dispose() of all custom widgets is not executed. I wrote a demo that indicates what I want to express.

    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: AppHomeWidget(),
        );
      }
    }
    
    
    
    class AppHomeWidget extends StatefulWidget{
      @override
      State<StatefulWidget> createState() {
        return AppHomeState();
      }
    }
    
    class AppHomeState extends State<AppHomeWidget>{
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          backgroundColor: Colors.white,
          body: Column(
            children: <Widget>[
              CustomWidget(),
              Text("text")
            ],
          ),
        );
      }
    
      @override
      void dispose() {
        super.dispose();
        print("AppHomeWidget dispose");
      }
    
    }
    
    
    class CustomWidget extends StatefulWidget{
    
      @override
      State<StatefulWidget> createState() {
        return SecondScreenState();
      }
    }
    
    class SecondScreenState extends State<StatefulWidget> {
      @override
      Widget build(BuildContext context) {
        return Center(
            child: new Text('CustomWidget')
        );
      }
    
      @override
      void dispose() {
        super.dispose();
        print("CustomWidget dispose");
      }
    }

    This demo has only one page. This page is also the last page of the application. In my actual project, it is the project's home page. Before it has a guide page, the login page is just that they have been closed. The home page is the end of the application. A page, similar to my demo, I don't know why, AppHomeWidget dispose and CustomWidget dispose are not printed.

  3. HQiang commented on Sep 20, 2019

    @HQiang
    Author

    In short, when the last page of the application is closed, all widgets' dispose() on this page will not be executed.

  4. escamoteur commented on Sep 20, 2019

    @escamoteur
    Contributor

    @dblokhin Why the thumbs down if this code reproduces the problem?

  5. escamoteur commented on Sep 20, 2019

    @escamoteur
    Contributor

    @tvolkert is this by design?

  6. added
    frameworkflutter/packages/flutter repository. See also f: labels.
    and removed
    d: stackoverflowGood question for Stack Overflow
    on Sep 20, 2019
  7. changed the title [-]dispose() is not call[/-] [+]dispose() of Stateful widgets is not called when the App is exited by pressing the backbutton[/+] on Sep 20, 2019
  8. dblokhin commented on Sep 20, 2019

    @dblokhin

    @escamoteur the code was not fenced and highlighted. Currently it's nice. :)

  9. HQiang commented on Sep 20, 2019

    @HQiang
    Author

    I think this is a big problem. When I want to quit the application, I want to release some resources. Dispose() does not execute. I really don't know how to implement the resource shutdown. I think this problem should be faced by everyone. How to solve it? I want the answer, I am going crazy.

  10. escamoteur commented on Sep 20, 2019

    @escamoteur
    Contributor
  11. HQiang commented on Sep 20, 2019

    @HQiang
    Author

    @escamoteur Ok, thank you, rest on the weekend, I will try the company next Monday, thank you again, thank you

  12. dblokhin commented on Sep 20, 2019

    @dblokhin

    A question is why the state of CustomWidget extends State<StatefulWidget>. I wasn't able to check it but my guess is its the problem. I don't think it is a proper way to make a stateful widget.

  13. escamoteur commented on Sep 20, 2019

    @escamoteur
    Contributor

    Hey you have a sharp eye. It has to be State but I guess that's not really the problem because CustomWidget is a State full Widget. So this should only make problems when you try to access the widget from the state.
    But I will give it a try.

  14. 71 remaining items

  15. dnfield commented on Aug 14, 2023

    @dnfield
    Contributor

    I have not closely read this entire thread, but it seems like there are two main concerns here:

    • Cleaning up resources upon process exit.
    • Cleaning up resources when the Flutter engine is destroyed (perhaps including Dart VM shutdown), but the process (perhaps including the Dart VM) is still alive.

    For the first case, I'm a bit at a loss. Any truly critical resources should just get cleaned up by the OS on process exit. If the resources you want to clean up are things like "send a network request" or "write to the file system," there's really no way to ensure the process can do that before being killed (the device has been powered off, the OS has killed you for memory pressure reasons, a privileged process has killed you with immediate effect, etc.).

    For the second case, there are a number of ways to handle this already before you shut down the engine (for example, send a message to the process that would cause it to pump a new and empty widget tree).

    I'd find it helpful to hear more about what kind of resources people need to clean up and why the current mechanisms aren't sufficient. For the first case, on platforms where it's well supported (namely desktop), WidgetsBindingObserver.didRequestAppExit can help with the first request (but only to a point, it will not be called e.g. if the power suddenly fails or the process is suddenly killed). For the second case, it's a little harder - but embedding Flutter into another application in general is a little bit harder.

  16. amigo-wangwx commented on Oct 7, 2023

    @amigo-wangwx

    My current situation is that the hybrid development of Flutter is only as part of the app. Click a button from the homepage to enter the Flutter map page. I need to call the dispose() method when closing flutter to tell the AndroidView to destroy the map, but the current mechanism has no way. callback received

  17. DamnBlack99 commented on Aug 1, 2024

    @DamnBlack99

    Hey.
    WTS?.
    Still there?.

  18. flo-at commented on Sep 9, 2024

    @flo-at

    This is really hard to work around. I need to have a global registry of resources that I have to manually dispose because of this. It is mentioned in the documentation though, so I guess it's not a bug but correct - but very unexpected - behaviour.

  19. escamoteur commented on Sep 9, 2024

    @escamoteur
    Contributor
  20. flo-at commented on Sep 10, 2024

    @flo-at

    In that particular case it's a thread that does some background rendering for a texture widget.

  21. escamoteur commented on Sep 10, 2024

    @escamoteur
    Contributor
  22. flo-at commented on Sep 10, 2024

    @flo-at

    In the end it will, but at least on Windows it does so with an abort message box.

  23. escamoteur commented on Sep 10, 2024

    @escamoteur
    Contributor
  24. flo-at commented on Sep 10, 2024

    @flo-at

    In the documentation for NativeFinalizer it reads:

    This means NativeFinalizer can not be relied upon for running actions on the programs exit.

    For now I can live with the error. There are workaround to get around this, it's just inconvenient.

  25. ndusart commented on Sep 12, 2024

    @ndusart

    @escamoteur unfortunately, relying on NativeFinalizer is not portable (#132404) and is not triggered on Linux platform.

    This needs some cleaning here in Flutter to have a standard way to release native resources on app exit (that is when Dart VM shutdown and before process exits) which is cross-platform and then clearly document this.

  26. icodeyou commented on Feb 22, 2025

    @icodeyou

    Any update on this ? This is a problem for me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projectdependency: androidAndroid team may need to help usfound in release: 3.3Found to occur in 3.3found in release: 3.7Found to occur in 3.7frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onplatform-androidAndroid applications specificallyteam-androidOwned by Android platform teamtriaged-androidTriaged by Android platform team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions