以前我們在iOS或Android研究生命週期時
通常研究的對象是ViewController或Activity/Fragment
不過在Flutter,由於「Everything is a Widget」
所以我們這次討論的對象是Widget
然而Widget有分兩種:善變的StatefulWidget
跟穩重的StatelessWidget
既然stless這麼穩重當然不必多言
那麼我們就把焦點放在stful身上
先上一張圖
來源(聽說是官方的,但不可考)
這張圖說明了一個StatefulWidget build完之後
除了dispose之外
可能有兩條路
內部
的狀態接收
到了新的組態而不管是哪條路
之後都會再call一次build
再來一張
出處:Flutter實戰 > 第三章:基礎組件 > 3.1 Widget簡介 > 3.1.6 State
我把它們分成三類,簡短解讀如下(文末有對照表)
更新
= 使用舊的widget
widget lifecycle中的各個步驟我覺得都很明確
只有這個didUpdateWidget我覺得有點混亂
以下根據各方面說明
//Widget這個Class裡面有個canUpdate
static bool canUpdate(Widget oldWidget, Widget newWidget) {
return oldWidget.runtimeType == newWidget.runtimeType
&& oldWidget.key == newWidget.key;
}
Key: 这个key属性类似于React/Vue中的key,主要的作用是决定是否在下一次build时复用旧的widget,决定的条件在canUpdate()方法中。
canUpdate是一个静态方法,它主要用于在Widget树重新build时复用旧的widget,
其实具体来说,应该是:是否用新的Widget对象去更新旧UI树上所对应的Element对象的配置;
通过其源码我们可以看到,只要newWidget与oldWidget的runtimeType和key同时相等时就会用newWidget去更新Element对象的配置,否则就会创建新的Element。didUpdateWidget():在widget重新构建时,Flutter framework会调用Widget.canUpdate来检测Widget树中同一位置的新旧节点,然后决定是否需要更新,
如果Widget.canUpdate返回true则会调用此回调。
也就是说在在新旧widget的key和runtimeType同时相等时didUpdateWidget()就会被调用。
父widget
build之後就算setState裡面什麼都沒寫也會觸發
存成變數
,就不會呼叫不同的子widget
,又會呼叫了Today Preview裡面示範的是單一widget自己本身life cycle呼叫的順序
下面幾張圖呈現了不同階段自己與child的life cycle (pls開頭的就是child XD)
這部分Flutter跟Android比較像
並沒有一個App級的通知
而是由各頁面各自處理⚠️⚠️⚠️
另外比較大的差異
就是Flutter沒有will/did的概念⚠️⚠️⚠️
它都是did
以AppLifecycleState這個enum來說
總共有四個狀態
所以如果想要做到跟一些金融App一樣
要進背景前噴霧一下>////<
看起來是沒辦法直接靠AppLifecycleState做到
所以Today Preview展示了回前景後驗證的動作
只要四步驟即可:
WidgetsBindingObserver
這個interfacevoid didChangeAppLifecycleState(AppLifecycleState state)
PS. 講到iOS App Life Cycle 一定要秀一下這張經典圖
iOS | Android | Flutter |
---|---|---|
init | onCreate | createState |
viewDidLoad | initState | |
viewWillAppear | onStart | 這個沒有真的滿傷的⚠️⚠️⚠️ |
viewDidLayoutSubviews | build | |
viewDidAppear | onResume | |
viewWillDisappear | onPause | |
viewDidDisappear | onStop | |
removeFromSuperview | deactivate | |
deinit | onDestroy | dispose |
WillEnterForeground | onRestart | |
DidBecomeActive | onStart | resumed |
WillResignActive | onPause | 這個沒有對金融業也滿傷的⚠️⚠️⚠️ |
DidEnterBackground | onStop | paused |
本集內容Android版請見:iOS Developer Learning Android. Lesson 04
下集預告:InheritedWidget