search
LoginSignup
67
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Flutterアプリのライフサイクル

はじめに

Flutterアプリのライフサイクルについてまとめています。Flutterのライフサイクルというと、

  • アプリ (AppLifecycleState) ← 今回の内容
  • 画面 (StatefulWidget)

の2種類がありますが、今回は上のアプリ自体のライフサイクルについての内容です。

StatefulWidgetのライフサイクルについては、Flutter StatefulWidgetのライフサイクルにまとめていますので、参照してください。

アプリのライフサイクル一覧とプラットフォームの対応関係

AppLifecycleStateの状態遷移と状態一覧を以下に示します。
スクリーンショット 2020-02-17 20.02.01.png

基本的にプラットフォーム側の状態をFlutterアプリの状態として再定義している感じですが、iOSのライフサイクルに近いと思います。なお、iOSのライフサイクルは詳しくなく、AndroidエンジニアのためのiOSのUIViewControllerのライフサイクルとAndroidのActivityのライフサイクル比較を参考にさせていただきました。間違いがあればコメントでご指摘いただけると幸いです。

inactivepausedの違いは、画面が表示されているか否かの違いの様子です。

状態 内容 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

参考文献

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
67
Help us understand the problem. What are the problem?