Search code examples
flutterapplication-lifecycle

Flutter: How to track app lifecycle without a widget


I'm involved with the FlutterSound project which is shipped as a package containing an api that, for the purposes of this question, doesn't contain a widget.

The api needs to handle events when the application changes its state (AppLifecycleState.pause/resume). (we need to stop/resume audio when the app is paused/resumed).

I can see how to do this in a widget using WidgetsBindingObserver but the api needs this same info without having to rely on a widget.

The SchedulerBinding class has a method handleAppLifecycleStateChanged which seems to provide the required info but its unclear how to implement this outside of a widget.


Solution

  • Below is a code sample that can listen to AppLifecycleState change events without directly involving a widget:

    import 'package:flutter/material.dart';
    
    class MyLibrary with WidgetsBindingObserver {
      AppLifecycleState _state;
    
      AppLifecycleState get state => _state;
    
      MyLibrary() {
        WidgetsBinding.instance.addObserver(this);
      }
    
      /// make sure the clients of this library invoke the dispose method
      /// so that the observer can be unregistered
      void dispose() {
        WidgetsBinding.instance.removeObserver(this);
      }
    
      @override
      void didChangeAppLifecycleState(AppLifecycleState state) {
        this._state = state;
      }
    
      void someFunctionality() {
        // your library feature
      }
    }
    

    Now you can instantiate the library in a flutter widget, for instance, from which point it will start listening to any change in AppLifecycleState.

    Please note that, the above code doesn't take care of redundant bindings. For example, if the client of your library is meant to initialize the library more than once in different places, the didChangeAppLifecycleState() method will be triggered multiple times per state change (depending on the number of instances of the library that were created). Also I'm unsure whether the solution proposed conforms to flutter best practices. Nevertheless it solves the problem and hope it helps!