State 的生命週期,定義了 Widget 的加載到構建的全過程,可以利用其回調機制根據 Widget 的狀態選擇合適的時機做合適的事情。而 APP 的生命週期,則定義了 APP 從啓動到退出的全過程
如果想在對應的 APP 的生命週期事件中做相應的處理,比如 APP 從後臺進入前臺、從前臺退到後臺,或是在 UI 繪製完後做一些處理,則可以應用 WidgetsBindingObserver 類來實現
WidgetsBindingObserver 中的回調方法
// Accessibility 相關特性回調
void didChangeAccessibilityFeatures() { }
// App 生命週期改變回調
void didChangeAppLifecycleState(AppLifecycleState state) { }
// 本地化語言改變回調
void didChangeLocales(List<Locale> locale) { }
// 系統窗口相關改變回調
void didChangeMetrics() { }
// 系統亮度改變回調
void didChangePlatformBrightness() { }
// 文本縮放係數改變回調
void didChangeTextScaleFactor() { }
// 內存不足警告回調
void didHaveMemoryPressure() { }
// 頁面 pop
Future<bool> didPopRoute() => Future<bool>.value(false);
// 頁面 push
Future<bool> didPushRoute(String route) => Future<bool>.value(false);
要使用以上回調方法,只需通過給 WidgetsBindingObserver 單例對象設置監聽器即可監聽相關回調方法
生命週期回調
didChangeAppLifecycleState 回調方法中,有一個參數類型爲 AppLifecycleState 的枚舉類,這個枚舉類是 Flutter 對 App 生命週期狀態的封裝,常用的狀態包括 inactive、paused、resumed
- inactive:處在不活動狀態,無法處理用戶響應
- paused:不可見且不能響應用戶的輸入,但在後臺繼續活動中
- resumed:可見的,且能響應用戶的輸入
class AppLifecycleReactor extends StatefulWidget {
const AppLifecycleReactor({ Key key }) : super(key: key);
@override
_AppLifecycleReactorState createState() => _AppLifecycleReactorState();
}
class _AppLifecycleReactorState extends State<AppLifecycleReactor> with WidgetsBindingObserver {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);// 註冊監聽器
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);// 移除監聽器
super.dispose();
}
AppLifecycleState _notification;
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
print("$state");
}
}
可以試着切換下前後臺,觀察下控制檯輸出的 App 狀態
- 從前臺退到後臺,控制檯打印的 App 生命週期變化如下:
AppLifecycleState.resumed->AppLifecycleState.inactive->AppLifecycleState.paused
- 從後臺切換回前臺,控制檯打印的 App 生命週期變化如下:
AppLifecycleState.paused->AppLifecycleState.inactive->AppLifecycleState.resumed
幀繪製回調
有時除了需要監聽 App 的生命週期回調外,還需要在組件完成渲染後做一些與顯示相關的其他處理,比如切換線程等,此時可以使用 WidgetsBinding 來實現
WidgetsBinding 提供了單次 Frame 繪製回調及實時 Frame 繪製回調兩種機制
- 單次 Frame 繪製回調:通過 addPostFrameCallback 實現。在當前 Frame 繪製完後進行回調,且只會回調一次,如果需要多次回調則需設置多次
WidgetsBindingObserver.instance.addPostFrameCallback((_){
print("addPostFrameCallback 繪製回調"); // 只回調一次
});
- 實時 Frame 繪製回調:通過 addPersistentFrameCallback 實現。在每次繪製 Frame 結束後進行回調
WidgetsBindingObserver.instance.addPersistentFrameCallback((_){
print("addPersistentFrameCallback 繪製回調"); // 每幀都回調
});