[基盤]ライフサイクルイベントを取得する方法

動作環境: Flutter 2.8.1 Dart 2.15.1
LINEでこのページを共有するTwitterでこのページを共有するこのページをはてなブックマークに追加

ユーザーが別のアプリに切り替えたときや、切り替えてまた戻ってきたときのイベントを捕捉して何か処理をしたいときがあります。

そのようなときはdidChangeAppLifecycleStateAppLifecycleStateを取得して状態をチェックするとよいです。
例を見ていきましょう。

lib/main.dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
@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');
if (state == AppLifecycleState.inactive) {
print('entered inactive!');
} else if (state == AppLifecycleState.resumed) {
print('entered resumed!');
} else if (state == AppLifecycleState.paused) {
print('entered paused!');
} else if (state == AppLifecycleState.detached) {
print('entered detached!');
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'アプリのライフサイクルを確認する',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const Scaffold(
body: Center(
child: Text('Hello!!'),
),
));
}
}

まず、ライフサイクルイベントを受け取る準備をする必要があります。
以下のコードを見てください。

lib/main.dart
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
@override
void initState() {
super.initState();
WidgetsBinding.instance?.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance?.removeObserver(this);
super.dispose();
}

14行目のクラスを定義するところでWidgetsBindingObserverを読み込みます。
あとは18行目のようにaddObserverメソッドを実行すればライフサイクルイベントを受け取るための準備が完了します。

また、インスタンスが破棄されたときには23行目のようにライフサイクルイベントを監視する設定もremoveObserberメソッドで除去しておきましょう。

次はライフサイクルイベントを受け取るコードをみていきましょう。
以下のコードを見てください。

lib/main.dart
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
print('state = $state');
if (state == AppLifecycleState.inactive) {
print('entered inactive!');
} else if (state == AppLifecycleState.paused) {
print('entered paused!');
} else if (state == AppLifecycleState.detached) {
print('entered detached!');
} else if (state == AppLifecycleState.resumed) {
print('entered resumed!');
}
}

27行目から始まるdidChangeAppLifecycleStateでアプリのライフサイクルイベントを受け取っています。
パラメーターとしてAppLifecycleStateの型を持つstateを取得できます。

この状態でアプリをビルドして非表示にしたり、復帰させたりするとデバッグコンソールにそれぞれのstateで指定した文字列がprintで表示されます。

flutter: state = AppLifecycleState.inactive
flutter: entered inactive!
flutter: state = AppLifecycleState.paused
flutter: entered paused!
flutter: state = AppLifecycleState.inactive
flutter: entered inactive!
flutter: state = AppLifecycleState.resumed
flutter: entered resumed!

AppLifecycleStateの値をざっくり分類するとinactive, paused, detachedの三つはアプリが非アクティブになったときに発生するイベントでresumedは非アクティブの状態からアクティブな状態に復帰した(= アプリがフォアグラウンドになった)ときに発生するイベントです。

inactive, paused, detachedの分類はオフィシャルのドキュメントにも定義されてありますが私には正直なところ難しくてよくわかりませんでした。FlutterやiOS,Androidの仕組みを詳しく理解していないと、ドキュメントだけでは正確に把握することは難しそうです。

実機で動かしてみて発生したイベントを確認し、どのイベントに対応したコードを書くべきかを考えるのがよさそうです。