Android Architecture Components (第二篇)

Android Architecture Components 源碼分析 第二篇

本文已授權(quán)我就是馬云飛公眾號獨家發(fā)布。

說是源碼分析有點,其實就是簡單的根據(jù)源碼梳理一遍整體的LiveData,ViewModel和Lifecycle各個部分是如何工作的,由于本人水平有限,如果文中有錯誤的地方,歡迎指正。

Android Architecture Components 源碼分析系列文章

  1. Android Architecture Components 第一篇,介紹生命周期的感知。
  2. Android Architecture Components 第二篇,介紹ViewModel的控制。
  3. 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é)一下都做了什么。

  1. 查找當(dāng)前的Activity/Fragment中是否有已經(jīng)添加的HoldFragment,有則返回。
  2. 查找當(dāng)前的Activity/Fragment是否有已經(jīng)創(chuàng)建但是并未添加的HoldFragment,有則返回。
  3. 注冊Activity/Fragment的生命周期監(jiān)聽。
  4. 創(chuàng)建新的HoldeFragment,并添加的緩存列表。
  5. HoldFragment在關(guān)聯(lián)到Activity/Fragment之后會在緩存中去掉當(dāng)前的Activity/Fragment對應(yīng)的HoldFragment
  6. 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相對宿主是唯一的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,967評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,273評論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,870評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,742評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,527評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,010評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,108評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,250評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,769評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,656評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,853評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,371評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,103評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,472評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,717評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,487評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,815評論 2 372

推薦閱讀更多精彩內(nèi)容