2020年2月10日 星期一

[Android] 螢幕旋轉時 child fragment 和 parent fragment onCreate 執行順序

markdown 最近遇到問題的場景是這樣的,在某個 parent fragment 中用 ViewPager 包含了兩個 child fragment,在 parent fragment 中有儲存了一些變數供給 child fragment 使用,這些變數在 parent fragment 中的 onCreate 初始化,在 child fragment 的 onCreate 中使用。 我預設 parent fragment 的 onCreate 會在 child fragment 的 onCreate 之前執行,這很合理阿,畢竟我們總是先載入 parent fragment 不是嗎? 原本這段程式碼運作的很好,直到有一天測試螢幕轉向,child fragment 的 onCreate 中拋出了 NullPointerException,顯示 parent fragment 中的變數並未初始化,該變數是 null。我發現當螢幕轉向時,child fragment 的 onCreate 會在 parent fragment 的 onCreate 之前執行,導致了這個 exception,這與我先前的認知相反,讓我很驚訝。 查了資料後才發現,原因是當螢幕轉向時,fragment manager 會重新 create 它管理的 fragment,而重新 create 的時間點就是在 [Fragment class](https://developer.android.com/jetpack/androidx/releases/fragment) 的 onCreate 裡面。因此,在我的 parent fragment onCreate 裡面呼叫 super.onCreate 的時候,child fragment 就在這時被 create 出來,並且呼叫了 child fragment 的 onCreate。 仔細想想,這個行為也不是沒有道理,如果 fragment manager 不在 Fragment class 的 onCreate 中去重建 child fragment,它還能在哪個時間點做這件事呢?但是我懷疑有多少人在一開始就查覺到這件事,而不是像我一樣遇到 crash 了才發現。 在查詢 fragment lifecycle 資料時,也看到 [square](https://developer.squareup.com/blog/advocating-against-android-fragments/) 有文章對 fragment 相當感冒,表示應該也有很多人對 fragment lifecycle 的複雜度覺得很難搞吧。 --- Reference: * [After the rotate, onCreate() Fragment is called before onCreate() FragmentActivity](https://stackoverflow.com/questions/14093438/after-the-rotate-oncreate-fragment-is-called-before-oncreate-fragmentactivi) * [Advocating Against Android Fragments](https://developer.squareup.com/blog/advocating-against-android-fragments/) * [Flow和Mortar的调查](https://github.com/hehonghui/android-tech-frontier/tree/master/androidweekly/Square%20%E5%BC%80%E6%BA%90%E5%BA%93Flow%E5%92%8CMortar%E7%9A%84%E4%BB%8B%E7%BB%8D)

沒有留言:

張貼留言