起動しているアプリがバックグラウンド実行になった時、またはアクティブ状態に再開した等を検知して何か処理を実行したいことがあります。
そういったアプリのライフサイクルは、Flutterでは enum AppLifecycleState
として定義されています。
enum AppLifecycleState {
detached,
resumed,
inactive,
hidden,
paused,
}
これらのライフサイクル変更をRiverpodのProviderを使用して監視できるようにしましょう👍
全体の実装コードは以下のサンプルリポジトリの該当ファイルで確認できます↓
AppLifecycleStateを持つNotifierを作成
Notifierクラスで AppLifecycleState
の変更を検知して状態を更新するために WidgetsBindingObserver
ミックスインを使用しています。
class AppLifecycle extends _$AppLifecycle with WidgetsBindingObserver {
AppLifecycleState build() {
// プロバイダ構築時に監視を開始。
final binding = WidgetsBinding.instance..addObserver(this);
// プロバイダが破棄された時に監視を解除。
ref.onDispose(() => binding.removeObserver(this));
// 初期値として `resumed` を返している。
return AppLifecycleState.resumed;
}
void didChangeAppLifecycleState(AppLifecycleState state) {
// `AppLifecycleState` の変更を検知してNotifierが持つ状態を更新。
this.state = state;
super.didChangeAppLifecycleState(state);
}
}
Notifierの build()
メソッド内で、監視の開始を行い、 ref.onDispose
を使ってプロバイダが破棄された時に監視を解除するようにします。
そして、 didChangeAppLifecycleState()
メソッドをオーバーライドし、AppLifecycleState
の変更を検知して state
を更新しています。
super
を使って継承元の didChangeAppLifecycleState
メソッドも実行しておきましょう。
Widgetからの使用例
ref.listen
を使用してアプリのライフサイクルを検知する例です。
ref
が使用できる箇所であれば同じようにどこでも監視可能ですし、状態によってUIを更新したい場合は ref.watch
を使用できます。
行いたい処理の責務にあった箇所でプロバイダを購読してライフサイクルを取得しましょう。
class App extends ConsumerWidget {
const App({
super.key,
});
Widget build(BuildContext context, WidgetRef ref) {
// appLifecycleProviderの状態変更を監視
ref.listen(
appLifecycleProvider,
// `next` に変更後の `AppLifecycleState` が入っています。
// 任意の処理を行いましょう。
(previous, next) => debugPrint('Previous: $previous, Next: $next'),
);
return const SplashPage();
}
}
参考元
Riverpod作者であるRemiさんのこちらのポスト内コードを参考にさせていただきました。