はじめに
Flutterアプリのライフサイクルについてまとめています。Flutterのライフサイクルというと、
- アプリ (
AppLifecycleState
) ← 今回の内容 - 画面 (
StatefulWidget
)
の2種類がありますが、今回は上のアプリ自体のライフサイクルについての内容です。
StatefulWidget
のライフサイクルについては、Flutter StatefulWidgetのライフサイクルにまとめていますので、参照してください。
アプリのライフサイクル一覧とプラットフォームの対応関係
AppLifecycleState
の状態遷移と状態一覧を以下に示します。
基本的にプラットフォーム側の状態をFlutterアプリの状態として再定義している感じですが、iOSのライフサイクルに近いと思います。なお、iOSのライフサイクルは詳しくなく、AndroidエンジニアのためのiOSのUIViewControllerのライフサイクルとAndroidのActivityのライフサイクル比較を参考にさせていただきました。間違いがあればコメントでご指摘いただけると幸いです。
inactive
とpaused
の違いは、画面が表示されているか否かの違いの様子です。
状態 | 内容 | Android | iOS |
---|---|---|---|
inactive | アプリは表示されているが、フォーカスがあたっていない状態 | onStart, onPause | viewDidLoad |
paused | アプリがバックグラウンドに遷移し(最前面に表示されてない)、入力不可な一時停止状態 | onPause | viewWillDisappear viewDidDisappear |
resumed | アプリがフォアグランドに遷移し(paused状態から復帰)、復帰処理用の状態 | onResume | viewWillAppear viewDidAppear |
detached | アプリが終了する時に通る終了処理用の状態 | onDestroy | dealloc |
AndroidのonSaveInstanceStateの様な仕組みはあるのか?
現状なさそうです。
AppLifecycleState
の状態を見て、必要であれば自分で対応する必要があります。
状態遷移ユースケース
いくつかのユースケースで状態遷移の動作を確認してみました。
WidgetsBindingObserverを利用するとAppLifecycleStateの状態が取得出来ます。
その他、SystemChannels.lifecycle (詳細はこちらにまとめてます。) を利用しても取得可能です。
確認のためのソースコード
class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
AppLifecycleState _state;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
print('state = $state');
}
アプリ起動
イベント発生なし
画面回転
イベント発生なし
アプリ終了
I/flutter (13730): state = AppLifecycleState.inactive
I/flutter (13730): state = AppLifecycleState.paused
I/flutter (13730): state = AppLifecycleState.detached
ホームボタンを押す
I/flutter (13730): state = AppLifecycleState.inactive
I/flutter (13730): state = AppLifecycleState.paused
画面OFF
I/flutter (15366): state = AppLifecycleState.inactive
I/flutter (15366): state = AppLifecycleState.paused
アプリを履歴から復帰
I/flutter (13730): state = AppLifecycleState.resumed
画面分割で起動
I/flutter (13252): state = AppLifecycleState.inactive
画面分割状態でサブ画面 (下画面) のアプリを終了
I/flutter (13252): state = AppLifecycleState.inactive
画面分割状態でサブ画面 (下画面) で新しいアプリを選択して、画面を2分割に戻る
I/flutter (13252): state = AppLifecycleState.resumed