Android Architecture Components 源碼分析 第二篇
本文已授權(quán)我就是馬云飛公眾號獨家發(fā)布。
說是源碼分析有點,其實就是簡單的根據(jù)源碼梳理一遍整體的LiveData,ViewModel和Lifecycle各個部分是如何工作的,由于本人水平有限,如果文中有錯誤的地方,歡迎指正。
Android Architecture Components 源碼分析系列文章
- Android Architecture Components 第一篇,介紹生命周期的感知。
- Android Architecture Components 第二篇,介紹ViewModel的控制。
- Android Architecture Components 第三篇,介紹LiveDate和LifeRegistry的協(xié)同操作。
作為MVVM 系列的第二篇,我們來看一下之前提出的第二個問題,就是ViewModel是如果控制生命周期的,并且保證在一定范圍內(nèi)的唯一性。
ViewModel 的生命周期
先上一張官方的生命周期的圖:
可以看到ViewModel只有一個生命周期函數(shù),那就是onCleared(),會在Activity的onDestroy之后執(zhí)行, 那么相對應(yīng)Fragment的生命周期是再哪個函數(shù)之后執(zhí)行?這里先劇透一下,也是在onDestroy之后執(zhí)行。
在看官方的實現(xiàn)之前,我們先簡單的想一下怎么才能實現(xiàn)Activity/Fragment生命周期函數(shù)的監(jiān)聽?思考三秒鐘,聯(lián)想到上一篇中的做法,可以想到利用Fragment和Activity中添加的Fragment來感知宿主的生命周期。并且這里我們只需要監(jiān)聽銷毀時候的函數(shù)就行。下面進(jìn)行具體的分析。
ViewModel的實現(xiàn)過程
給出一個最簡單的創(chuàng)建的示例:
MainActivityViewModel viewModel=ViewModelProviders.of(this).get(MainActivityViewModel.class);
代碼很好理解,獲取當(dāng)前類的ViewModel提供者,之后在傳入需要獲得的ViewModel的類型。先看一下ViewModelProviders都做了什么?
如果傳入的this是Fragment就先判斷下是否已經(jīng)關(guān)聯(lián)到Activity上,沒有就拋異常。之后就初始化一個sDefaultFactory,用于創(chuàng)建ViewModelProvider。在ViewModelProvider的構(gòu)造函數(shù)中還需要一個ViewModelStores。
兩個工廠方法用于創(chuàng)建ViewModelStore。接下來就是本文的重點了。還是以Activity為例,F(xiàn)ragment的大同小異。
簡單說一下這個方法都做什么了。先獲取FragmentManager,查找當(dāng)前的Activity有沒有已經(jīng)添加過HoldFragment,沒有的話則去還沒有添加到Activity/Fragment的HoldFragment列表中去查詢,看看有沒有已經(jīng)創(chuàng)建的HoldFragment,只不過還沒有添加上去。如果還沒有的話那就創(chuàng)建一個新的HoldFragment,同時給Application注冊一個Activity的生命周期監(jiān)聽,再把創(chuàng)建的HoldFragment添加到緩存列表中。現(xiàn)在來看看這個HoldFragment。
擁有兩個屬性sHoldFragmentManager和mViewStore。在onCreate方法中執(zhí)行一個函數(shù),將在未添加到Activity/Fragment的HoldeFragment列表中刪除當(dāng)前的Activity/Fragment。然后在onDestory方法中調(diào)用mViewStore的clear方法,這里就會間接的調(diào)用到ViewModel的onCleared()方法。更多的細(xì)節(jié)可以去看源碼,這里簡單的總結(jié)一下都做了什么。
- 查找當(dāng)前的Activity/Fragment中是否有已經(jīng)添加的HoldFragment,有則返回。
- 查找當(dāng)前的Activity/Fragment是否有已經(jīng)創(chuàng)建但是并未添加的HoldFragment,有則返回。
- 注冊Activity/Fragment的生命周期監(jiān)聽。
- 創(chuàng)建新的HoldeFragment,并添加的緩存列表。
- HoldFragment在關(guān)聯(lián)到Activity/Fragment之后會在緩存中去掉當(dāng)前的Activity/Fragment對應(yīng)的HoldFragment
- HoldFragment在onDestory的時候會調(diào)用其成員變量mViewStore的clear方法。
回到之前創(chuàng)建ViewModelProvider的地方。
簡單看一下,代碼不難理解,先賦值成員變量,之后是查看ViewModelStore中是否有傳入類型的ViewModel,沒有的話就通過傳入的工廠類創(chuàng)建一個新的ViewModel 添加到ViewModelStore中。
這樣ViewModel的實現(xiàn)過程就差不多結(jié)束了,還是利用Fragment的方式去獲取生命周期,然后再利用工廠類來創(chuàng)建ViewModel。
關(guān)于在一定范圍內(nèi)的唯一性,因為ViewModelStore是HoldFragment的成員變量,HoldFragment是通過FragmentManager添加到指定的Activity/Fragment,那么對于當(dāng)前的宿主,只有一個HoldFragment,也就只有一個ViewModelStore,同時也就只有一個ViewModel。
總結(jié)
同樣使用的給宿主添加Fragment的方式來獲取宿主的生命周期,只不過現(xiàn)在只獲取銷毀的函數(shù)就可以。然后在HoldFragment中持有一個集合用于保存當(dāng)前宿主的ViewModel,在onDestory函數(shù)中調(diào)用集合的clear方法,間接調(diào)用到ViewModel的onCleared方法,實現(xiàn)生命周期的控制。同時使用TAG的方式添加Fragment
使得ViewModel相對宿主是唯一的。