-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
Problem
The Flutter widgets library provides the AppLifecycleListener so that applications can listen to changes in its state. These states are “resumed”, “inactive”, “hidden”, “paused”, and "detached".
- Detached - The application is still hosted by a Flutter engine but is detached from any host views. When the application is in this state, the engine is running without a view.
- Resumed - this corresponds to the app running in the foreground active state.
- Inactive - At least one view of the application is visible, but none have input focus. The application is otherwise running normally. This state corresponds to the Flutter host view running in the foreground inactive state. Apps transition to this state when: in a phone call, responding to a TouchID request, entering the app switcher or the control center, or the UIViewController hosting the Flutter app is transitioning.
- Hidden - All views of an application are hidden, either because the application is about to be paused
- Paused - The application is not currently visible to the user, and not responding to user input.
Currently, Flutter uses lifecycle events/notifications from the FlutterAppDelegate and FlutterViewController to determine the state and send it to the framework.
Proposal 1 - AppLifecycleState is per FlutterViewController/FlutterEngine
If the AppLifecycleState is per FlutterViewController/FlutterEngine, it should be determined by view events and scene events.
For example, let’s say an app has 2 scenes, each with a FlutterEngine/FlutterViewController. Under this proposal, if Scene 1 is backgrounded, you’d expect the state of the FlutterEngine in Scene 1 to be “paused” and the state of the FlutterEngine in Scene 2 to be “resumed”. With our current setup, both would be “resumed”.
The following events would need to be replaced:
- applicationBecameActive → sceneDidBecomeActive
- applicationWillResignActive → sceneWillResignActive
- applicationWillTerminate → sceneDidDisconnect
- applicationDidEnterBackground → sceneDidEnterBackground
- applicationWillEnterForeground → sceneWillEnterForeground
Pros:
- Essentially AppLifecycleState would act more as if it was “EngineLifecycleState” or “SceneLifecycleState”
- Less complex to implement
Cons:
- Not inline with the future of multi-view (see “Multi-View Consideration” below).
- May require changes in future if multi-view is adopted
Proposal 2 - AppLifecycleState is per Application
According to the documentation in app_lifecycle_state.h, these states should each be implemented with the whole application in mind rather than per-view. Each state should take into account multiple views in the following way:
- Resumed: when any view is shown
- Inactive: when all views are inactive
- Hidden: when all views are hidden
- Paused: not view specific
- Detached: not view specific
Source: Flutter Multi-Window API (PUBLICLY SHARED)
To make this happen, we’d probably introduce an internal-only ViewLifecycleState. This would track the state of the FlutterViewController and would be saved to the FlutterEngine. Then when a lifecycle event occurs, we’d get the ViewLifecycleState for each FlutterViewController in each FlutterEngine to determine the AppLifecycleState.
To access other FlutterViewControllers and FlutterEngines, we can iterate through the Scenes and iterate through each FlutterEngine they have connected (see Proposal 1of “Plugin lifecycle events”).
Pros:
- Inline with multi-view future
Cons: - No way to track “SceneLifecycleState”