前面部分,已經介紹過了,組件的構建渲染=> 傳送門api
在咱們原生Android(或者IOS)開發中,不少是否要在對應的生命週期作一些事件,例如App從後臺進入前臺,從前臺退入後臺(或被遮蓋),以及須要在確保UI繪製後作一些處理,這在咱們原生開發中很容易作到,那麼在Flutter中須要怎麼去作呢?安全
很簡單,給WidgetsBinding設置Observeride
class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver{
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);//添加觀察者
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
print("lifeChanged $state");
}
@override
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this);//銷燬
}
@override
Widget build(BuildContext context) {
return Container();
}
}
複製代碼
經過以上代碼,咱們能夠看到只要給WidgetsBinding的單例對象添加WidgetsBindingObserver,而後此類粘合(with)WidgetsBindingObserver抽象類,在初始化State的時候給WidgetsBinding設置Observer爲當前類,並在銷燬的時候移除Observer,此時咱們的State就具有WidgetsBindingObserver的回調了。post
(關於with的做用讀者可自行搜索相關關鍵字mixin、with)。字體
咱們看看WidgetsBindingObserver中具體有哪些回調:ui
abstract class WidgetsBindingObserver {
//路由彈出Future
Future<bool> didPopRoute() => Future<bool>.value(false);
//新的路由Future
Future<bool> didPushRoute(String route) => Future<bool>.value(false);
//系統窗口相關改變回調,例如旋轉
void didChangeMetrics() { }
//文字係數變化
void didChangeTextScaleFactor() { }
//本地化語言變化
void didChangeLocales(List<Locale> locale) { }
//生命週期變化
void didChangeAppLifecycleState(AppLifecycleState state) { }
//低內存回調
void didHaveMemoryPressure() { }
//當前系統改變了一些訪問性活動的回調
void didChangeAccessibilityFeatures() {}
}
複製代碼
能夠看到,常見的屏幕、字體、語言等變化都會經過此類實現進行回調,這裏咱們關注生命週期的變化方法didChangeAppLifecycleStatethis
void didChangeAppLifecycleState(AppLifecycleState state) { }
spa
這個方法有一個參數類型爲AppLifecycleState的枚舉類,咱們能夠根據它的狀態來處理咱們的一些任務code
enum AppLifecycleState {
resumed,
inactive,
paused,
suspending,
}
複製代碼
Flutter回調的生命週期與Android基本上差很少,這裏說一下回調比較特別的地方。server
以Android爲例,當咱們Activity建立的時候,流程是這樣的:
建立期:onCreate -> onStart -> onResume
進入後臺: onPause -> onStop
從後臺恢復:onRestart->onResume
而在Flutter中這整個流程是:
建立期: initState
進入後臺: inactive -> paused
從後臺恢復: inactive -> resumed
對比發現,在咱們頁面建立的時候不會觸發生命週期回調(didChangeAppLifecycleState),而在進入後臺和從後臺恢復的時候都會先調用inactive(可見,不可響應)而後調用paused(完全不可見)或者resumed(可見並可操做)。至於掛起(suspending)的回調,筆者暫時還不知道怎樣纔會觸發。
Tips:當生命週期可交互時(resumed)纔開始繪製Frame,生命週期變爲不可交互時(paused、suspending)會中止繪製Frame,這個後面分析Flutter啓動時會介紹。
有的時候咱們須要在Widget渲染以後作一些安全的操做,在Android中能夠經過View.post()插入消息隊列,這樣能夠保證在組件渲染後進行操做,那麼Flutter中有沒有這樣的API呢?固然有啦..
仍是咱們的WidgetsBinding
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_){
print("Frame has been rendered");
});
}
複製代碼
經過addPostFrameCallback能夠作一些安全的操做,在有些時候是頗有用的,它會在當前Frame繪製完後進行回調,並只會回調一次,若是要再次監聽須要再設置。
WidgetsBinding.instance.addPersistentFrameCallback((_){
print("Frame has been rendered");
});
複製代碼
這個api在每次繪製Frame結束後都會回調,咱們能夠利用它作一些幀率檢測。
這些都是比較經常使用的,更多有用好玩的api得你們本身去發現。