Flutter 中我們要拿到生命周期的回調(diào)會使用 WidgetsBindingObserver.當(dāng)我們啟動的第一個 Widget 就使用到 WidgetsBindingObserver 時,其初始啟動回調(diào)的執(zhí)行時機在兩個平臺表現(xiàn)不一致, 而且在 iOS release 和 debug 兩種模式下也會表現(xiàn)不一致。
我們用一個簡單 Demo 來實驗一下:
import 'package:flutter/widgets.dart';
class LifecycleWatcher extends StatefulWidget {
const LifecycleWatcher({Key? key}) : super(key: key);
@override
State<LifecycleWatcher> createState() => _LifecycleWatcherState();
}
class _LifecycleWatcherState extends State<LifecycleWatcher>
with WidgetsBindingObserver {
AppLifecycleState? _lastLifecycleState;
@override
void initState() {
super.initState();
WidgetsBinding.instance!.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance!.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
setState(() {
_lastLifecycleState = state;
});
}
@override
Widget build(BuildContext context) {
if (_lastLifecycleState == null) {
return const Text('This widget has not observed any lifecycle changes.');
}
return Text(
'The most recent lifecycle state this widget observed was: $_lastLifecycleState.');
}
}
void main() {
runApp(
const Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: LifecycleWatcher(),
),
),
);
}
上面是簡單的 WidgetsBindingObserver 使用,并且執(zhí)行回調(diào)的 AppLifecycleState 顯示在屏幕上。
flutter version 2.5.3 dart version 2.14.4 執(zhí)行結(jié)果:
-
iOS15.0
- debug 模式: 初始啟動 didChangeAppLifecycleState 不會執(zhí)行.
- release 模式: 初次安裝啟動 didChangeAppLifecycleState 不會執(zhí)行. 已安裝后再重新啟動執(zhí)行 AppLifecycleState.resumed.
Android: debug 和 release 模式下初次啟動 didChangeAppLifecycleState 都不會執(zhí)行。
所以如果我們在啟動第一個界面在 AppLifecycleState.resumed 里面做了一些事情,就要考慮到 iOS release 下初次啟動就會調(diào)用一次而 Android 不會調(diào)用的差異。
還有一個注意點 AppLifecycleState.resumed 在 iOS 原生系統(tǒng) Alert 彈窗關(guān)閉時也會調(diào)用,當(dāng)我們程序首次啟動時,可能會有很多系統(tǒng)的 Alert 彈窗,比如通知,網(wǎng)絡(luò)等權(quán)限彈框,所以 App 啟動時 AppLifecycleState.resumed 生命周期可能會觸發(fā)多次。