🔍

【Flutter】MVVMパターンでアプリのライフサイクル(中断・復帰)を検知する

2022/02/13に公開

結論

状態管理を担うクラスにWidgetsBindingObserverをwithすればOK😸

公式ドキュメントの例でも、StatefulWidgetのStateクラスにMixinしています。
同様にStateNotifier等を継承したクラスとも一緒に使えます。
https://api.flutter.dev/flutter/widgets/WidgetsBindingObserver-class.html

継承については、下記の記事がとてもわかりやすいので紹介します。
https://zenn.dev/iwaku/articles/2020-12-16-iwaku

StateNotifierにwithした例

簡単な例として、アプリを中断させると数字が減り、復帰させると数字が増えるサンプルを作ってみました。
全コード↓
https://github.com/nasubibocchi/app_lifecycle_state_mvvm

addObserverとremoveObserverを追加

状態管理クラス(今回の例では、StateNotifierを継承したクラス)の中に、addObserverとremoveObserverを実行するメソッドを作成します。

void _initialize() {
    WidgetsBinding.instance!.addObserver(this);
}

  void dispose() {
    WidgetsBinding.instance!.removeObserver(this);
    super.dispose();
  }

これで状態管理クラスのproviderが呼ばれた時にライフサイクル検知がスタートし、stateが破棄されるタイミングで検知が終わる(と思われます)。

実際にライフサイクルを検知して処理を実行する

上記と同じクラスの中に、ライフサイクルを検知する&実行したい処理を書きます。

下記の例では、decrementMuNumber()とincrementMyNumber()というメソッドを同クラスに作っておき、呼び出しています。
なんでもいいので、ここでは中身は省略しています。


  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    if (state == AppLifecycleState.inactive) {
      decrementMyNumber();
    }
    if (state == AppLifecycleState.resumed) {
      incrementMyNumber();
    }
  }

(ここ以外にメソッドを使用する予定がなければ、直で書いていいです。)

アプリのライフサイクルについて↓こちらを参考にしました。
https://qiita.com/kurun_pan/items/0c6de1313844a8cc1603

state初期化時にaddObserverする

さっき作った_initialize()という関数を、状態管理クラスの初期化時(Providerが呼ばれた時)に実行します。

class SamplePageViewModel extends StateNotifier<SamplePageState>
    with WidgetsBindingObserver {
  SamplePageViewModel(this._dataUseCase) : super(SamplePageState.loading()) {
    _initialize(); // <- ここ。
    // ・・・他の処理
  }

これを忘れると、検知が始まりません。

Discussion