
Fragivity是一個基于Fragment打造的單Activity框架,
開發者在使用同類框架時,往往都很關心Fragment的Lifecycle,Fragivity在這方面做了不少優化,解決了一些Navigation等其他框架中的痛點,
我們主要關心以下幾個case中的生命周期表現:
- 頁面跳轉/回傳
- 熄亮屏
- Configurations Change(螢屏旋轉等)
1. 頁面跳轉/回傳
表現
當從FirstFragment啟動SecondFragment時:
SecondFragment => onCreate
SecondFragment => onViewCreated
SecondFragment => onActivityCreated
SecondFragment => onStart
SecondFragment => onResume
FirstFragment => onPause
FirstFragment => onStop
- SecondFragment 進入創建流程;
- FirstFragment退出前臺,但是不走
onDestroyView,因為回傳時不需要重建視圖
當從SecondFragment回傳FirstFragment時:
SecondFragment => onPause
SecondFragment => onStop
SecondFragment => onDestroyView
SecondFragment => onDestroy
FirstFragment => onStart
FirstFragment => onResume
- SecondFragment 進入銷毀流程
- FirstFragment回傳到前臺,但是沒有重新
onCreateView
相對于Navigation等其他框架的改善在于避免了回傳時重新創建視圖,與Activity的行為一致,
實作原理
Navigation由于使用replace方式切換Fragment,所以在回退時需要重新onCreateView,Fragivity使用add替代replace,避免了回退時的Fragment重建,
這樣處理會帶來一個問題:切到“后臺”的Fragment視覺上被遮擋,但實質上仍然是attach狀態,其生命周期默認應該跟隨Activity一致,所以此處需要監聽BackStack的變化,當堆疊頂發生變化時(即有新的Fragment入堆疊),需要對進入“后臺”的Fragment進行performStop操作;反之進入“前臺”時也同樣處理,
2. 熄亮屏
表現
當前回退堆疊里有FirstFragment、SecondFragment兩個頁面,SecondFragment處于堆疊頂,此時熄滅/點亮螢屏:
SecondFragment => onPause
SecondFragment => onStop
SecondFragment => onStart
SecondFragment => onResume
- SecondFragment與宿主Activity的Lifecycle一致
- FirstFragment雖然也在堆疊中但是由于身處后臺,所以不受影響
實作原理
Fragivity使用add方式切換Fragment,即使Fragment處于“后臺”,由于是attached狀態,當點亮螢屏時,默認會隨Activity進行onStart、onResume,這顯然不是我們希望的,
Fragivity為進入回退堆疊的所有的Fragment都封裝了一個代理ReportFragment,

有時從系統層面直接對Fragment做hook不太方便,借助ReportFragment可以降低處理成本,有機會對被代理物件做一些手腳,
當點亮螢屏時,借助ReportFragment攔截系統分發給“后臺”Fragment的stateChange,實作其不回應Activity生命周期的需求,
3. Configurations Change(橫豎屏等)
表現
當前回退堆疊里有FirstFragment、SecondFragment兩個頁面,SecondFragment處于堆疊頂,此時旋轉螢屏:
SecondFragment => onPause
SecondFragment => onStop
SecondFragment => onDestroyView
FirstFragment => onDestroyView
SecondFragment => onViewCreated
SecondFragment => onActivityCreated
SecondFragment => onStart
SecondFragment => onResume
- 配置變化會觸發銷毀重建,銷毀流程中,堆疊內所有Fragment推進到
onDestroyView,Fragment的retainInstance=true,所以不執行onDestroy,處于“后臺”的FirstFragment由于已經執行過onStop,所以只執行onDestroyView,
Fragment只能使用默認建構式重建,所以Fragivity會為入堆疊的所有Fragment設定
retainInstance = true,這樣可以使用自定義建構式創建Fragment且不用擔心恢復重建的問題
- 重建流程中,SecondFragment正常重建,但是FirstFragment由于處于“后臺”為了提高性能,不進行重建,只有當回傳“前臺”時
SecondFragment旋轉螢屏后,再回退到FirstFragment:
SecondFragment => onPause
SecondFragment => onStop
SecondFragment => onDestroyView
SecondFragment => onDestroy
FirstFragment => onViewCreated
FirstFragment => onActivityCreated
FirstFragment => onStart
FirstFragment => onResume
- SecondFragment出堆疊銷毀
- FirstFragment進入“前臺”,進入創建流程
當配置變化引起銷毀重建時,只對前臺Fragment第一時間進行重建,對于后臺Fragment暫不重建,當堆疊內的Fragment數量很多時也不會影響重建性能,
實作原理
同樣需要借助ReportFragment做一些攔截:將是否處于“后臺”的狀態存入ViewModel,當恢復重建時識別其“后臺”身份,對dispatchResume進行攔截,
FIN
以上就是Fragivity中的Lifecycle處理思路,希望能為其他類似的需求提供參考,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/255928.html
標籤:其他
