原文地址: http://www.jianshu.com/p/963a...java
Android 官方架構組件在今年 5 月份 Google I/O 大會上被公佈, 直到 11 月份一直都是測試版, 因爲工做比較繁忙, 期間我只是看過相似的文章, 但沒有在實際項目中使用過, 更沒有看過源碼, 因此對這幾個組件的使用非常生疏, 同時也以爲這幾個組件很是高大上, 很是神祕!react
直到 11 月份 Android 官方架構組件正式版發佈, 而且 Google 也在 Support Library v26.1.0 之後的版本中內嵌了 Android 官方架構組件中的生命週期組件, 我想, 這是趨勢, 既然 Google 這麼推崇, 那我也是時候學習一波並將它們引入 MVPArms 框架了android
Github : 你的 Star 是我堅持的動力 ✊
由於想將 Android 官方架構組件引入 MVPArms 框架之中, 因此我認真學習了 Android 官方架構組件中除了 Room 以外的全部源碼, 以考察是否整個組件都適合引入 MVPArms 框架git
在學習完源碼事後, 發現 Android 官方架構組件其實並無想象的那麼高深, 原理反而是咱們在平常開發中都會用到的知識點, 那我就在文章的開頭先簡單的介紹下 Android 官方架構組件中的這幾個組件github
生命週期組件是 Android 官方架構組件中的核心組件, 它可使各類實例做爲觀察者與 Activity 和 Fragment 等具備生命週期特性的組件綁定在一塊兒, LiveData 和 ViewModel 都是基於此組件, 簡而言之就是, 你將須要綁定生命週期的實例註冊給該組件, 該組件就會在你指定的某個生命週期方法執行時通知這個實例網絡
應用場景不少, 好比以前在 MVP 架構中, 你須要在 Activity 執行 onCreate 時, 讓 Presenter 初始化一些操做, 這時就不用在 Activity 的 onCreate 中再調用 Presenter 的某個初始化方法了, 直接使用官方的生命週期組件便可完成, 在 Activity 執行 onDestroy 時須要釋放一些對象的資源, 也可使用到生命週期組件架構
LiveData 具備兩個功能, 第一個功能是觀察者模式, 在 Value 發生變化時通知以前註冊的全部觀察者, 第二功能是基於生命週期組件與 Activity 和 Fragment 等具備生命週期特性的組件綁定在一塊兒, 在生命週期發生改變時中止或恢復以前的事件app
簡而言之就是, 當某個頁面請求網絡數據成功後須要同步 UI, 但這個頁面已經不可見, 這時就會中止同步 UI 的操做框架
ViewModel 有兩個功能, 第一個功能可使 ViewModel 以及 ViewModel 中的數據在屏幕旋轉或配置更改引發的 Activity 重建時存活下來, 重建後數據可繼續使用, 第二個功能能夠幫助開發者輕易實現 Fragment 與 Fragment 之間, Activity 與 Fragment 之間的通信以及共享數據源碼分析
用法就很少說了, 此類文章和 Demo 太多了, 明白了它們的功能和應用場景後, 咱們才知道它們是否真的適合本身的需求, 而不是盲目跟風, 下面我就來分析下我是如何考察新技術, 以及如何判斷這些新技術是否有必要應用到本身的項目中
上面介紹了生命週期組件的功能, 這裏就來分析一下生命週期組件是否有必要引入個人框架 MVPArms
說到生命週期我就想到了我以前在 傳統MVP用在項目中是真的方便仍是累贅? 中討論的一個內容
如今市面上流行的 MVP 架構有兩種, 第一種是將 Activity 或 Fragment 做爲 View, 抽象一個 Presenter 層出來, 第二種是將 Activity 或 Fragment 做爲 Presenter, 抽象一個 View 層出來
第一種類型表明的框架有 MVPArms, 第二種類型表明的框架有 TheMVP, 固然第一種類型的 MVP 架構在市面上用的是最多的, 那麼第二種類型的優勢是什麼呢?
我在上面這篇文章也說過, 主要優點有兩個, 方便重用View, 以及 可直接與 Activity 或 Fragment 的生命週期作綁定, 這樣就能夠直接使用 Activity 或 Fragment 的生命週期, 不用再去作多餘的回調, 固然也有缺點, 我在文章中也有介紹, 有興趣的能夠去看看
第一種類型的 MVP 架構是不具備能夠和 Activity 或 Fragment 的生命週期直接作綁定的優點的, 因此非常嫉妒第二種類型的 MVP 架構, 這也是兩種類型的 MVP 架構最大的區別, 但你想的沒錯, 如今使用生命週期組件就可使第一種類型的 MVP 架構很輕易的具備綁定生命週期的優點, 如今第一種類型的 MVP 架構將如虎添翼
通過以上的分析, 我認爲生命週期組件對於個人框架來講是頗有必要的, 這將使平常開發更加便捷
LiveData 與 RxJava 都是基於觀察者模式, 功能上也有重合, Google 在官方文檔上也明確表示, 若是你正在使用 RxJava, Agera 等相似功能的庫, 只要你能正確的處理數據流的生命週期, 就徹底能夠繼續使用它們來替代 LiveData
Note: If you are already using a library like RxJava or Agera, you can continue using them instead of LiveData. But when you use them or other approaches, make sure you are handling the lifecycle properly such that your data streams pause when the related LifecycleOwner is stopped and the streams are destroyed when the LifecycleOwner is destroyed. You can also add the android.arch.lifecycle:reactivestreams artifact to use LiveData with another reactive streams library (for example, RxJava2).
從官方文檔能夠看出 Google 對此的建議就是 RxJava, Agera, LiveData 等相似功能的庫, 你只使用一個便可
LiveData 和 RxJava 的功能的確過於重合, 我也十分贊同 Google 官方的建議, 二者之中選擇其一就能夠了, 不必二者都引入項目, 而 MVPArms 框架, 也正好引入了 RxJava, 因此我也來分析分析在 MVPArms 框架中該選擇 LiveData 仍是 RxJava?
因而我認真的研究了其源碼, LiveData 具備兩個功能, 通知觀察者更新數據和根據生命週期中止和恢復以前的事件, 而 Rxjava 加上 RxLifecycle, RxJava 加上 AutoDispose, 或 Rxjava 加上生命週期組件, 也能夠輕易作到根據生命週期中止和恢復以前的事件, 在配上 Rxjava 強大的操做符, LiveData 能作的事 RxJava 都能作, LiveData 不能作的事 RxJava 也能作
而且 RxJava 不只僅只是 RxJava, 他仍是一個龐大的生態鏈, 他還有 RxCache, RxLifecycle, RxAndroid, RxPermission, Retrofit-Adapter 等大量而且強大的衍生庫, 咱們離開它作不少事都很是不便, 剛剛出生, 羽翼未豐的 LiveData 相比於 RxJava 將沒有任何優點, 甚至顯得很是簡陋
所以 LiveData 和 RxJava 之間若是隻能選擇一個的話, 我沒有任何理由選擇 LiveData
ViewModel 中有一個功能讓我十分驚豔, 也十分好奇, 它可使 ViewModel 以及 ViewModel 中的數據在屏幕旋轉或配置更改引發的 Activity 重建時存活下來, 重建後數據可繼續使用, 這個功能十分實用且十分重要, 由於以前也沒有一個官方解決方案, 因此我以爲頗有必要將這個功能引入 MVPArms 框架
一樣另一個功能, 它還能夠幫助開發者輕易實現 Fragment 與 Fragment 之間, Activity 與 Fragment 之間的通信以及共享數據, 一樣也正是我所須要的官方解決方案
但在我繼續深刻研究, 準備將它引入到項目中時, 卻發現 Google 將這個功能作了高度封裝並限制了它的使用範圍, 只能用於 ViewModel
但我想 Google 既然能讓 MVVM 框架中的 ViewModel 具備這些功能, 那我爲何不能將這個功能擴展出來提供給 MVP 框架中的 Presenter, 乃至其餘更多的模塊?
因而我認真的研究了其源碼, 準備經過修改源碼並封裝成庫的方式, 讓更多的開發者在更多的場景下可以使用到這些功能
要想改造 ViewModel 組件 天然要對它的整個源碼分析一遍, 知道其原理, 才知道如何下手
篇幅有限, 就來簡單的分析下源碼把, 源碼其實也就幾個類, 通過了層層封裝, 核心代碼就在一個叫作 HolderFragment 的 Fragment 中,
在我看來 ViewModel 組件 的核心原理也就是 HolderFragment 中的一行代碼實現的:
setRetainInstance(true);
setRetainInstance(boolean) 是 Fragment 中的一個方法, 我想不少人應該都知道這個方法的意義
簡單來講將這個方法設置爲 true 就可使當前 Fragment 在 Activity 重建時存活下來, 若是不設置或者設置爲 false, 當前 Fragment 會在 Activity 重建時一樣發生重建, 以致於被新建的對象所替代
意思是隻要將這個方法設置爲 true, Fragment 以及 Fragment 之中的全部數據都會在 Activity 重建時存活下來
這時咱們在 setRetainInstance(boolean) 爲 true 的 Fragment 中放一個專門用於存儲 ViewModel 的 Map, 天然 Map 中全部的 ViewModel 都會倖免於 Activity 重建
因而咱們讓 Activity, Fragment 都綁定一個這樣的 Fragment, 將 ViewModel 存放到這個 Fragment 的 Map 中, ViewModel 組件 就這樣實現了
想要知道如何改造, 那咱們就要明確此次改造的最終目的是什麼, 咱們的目的就是要讓 ViewModel 組件 能用於 Presenter, 乃至其餘更多的模塊, 不止是用於 ViewModel
那爲何 Google 官方的 ViewModel 組件 不能用於其餘模塊呢, 經過閱讀源碼能夠知道, 是由於 Google 把上文提到的 Map, 封裝了起來, 並無提供出去, 而且限制了 ViewModel 的構建方式
ViewModel 組件 讓一個新的 ViewModel 必須繼承於它的基類, 而且讓開發者必須提供一個 Factory 指明當前 ViewModel 的構建方式, ViewModel 組件 會在合適的時機, 主動去根據 Factory 構建 ViewModel 實例, 並放入 Map 中
這時整個構建過程都被 ViewModel 組件 掌控並被限制於 ViewModel, 因此我須要作的就是將 Map 和 ViewModel 的構建方式擴展出來, 將更多的控制權交給外部的開發者
通過上面的分析, 思路和方案都有了, 接下來就剩下如何把思路和方案實現了
因而我結合上文分析的思路和方案對官方源碼進行了改造並作了適當的優化, LifecycleModel 就這樣誕生了
這篇文章主要仍是講在完成一個目標前, 在從 0 到 1 期間進行的思路和分析的過程, 至於細節你若是感興趣的話仍是去看個人源碼把, 哈哈, 註釋很詳細哦!
Github : 你的 Star 是我堅持的動力 ✊
一個新技術是否真的適合本身仍是須要本身去考察, 不該該盲目跟風, 若是你只知道這個技術很火而後去用它, 不知道爲何用它, 用它的好處, 那你就會一直陷入被動學習的窘境, 一直在學習, 可是總以爲本身跟不上時代的進步, 擔驚受怕, 這是現代技術人大部分都存在的處境
至於最近鬧的沸沸揚揚的簡書 飽醉豚 事件, 自從簡書 CEO 站臺後, 已經再也不是當事人一我的的事, 而是關乎到簡書整個平臺, 既然這個 CEO 這麼傲氣, 這個平臺都不在意咱們這個羣體, 咱們也再也不去關注這個平臺就是了, 流量是跟着原創做者走仍是跟着平臺, 本身內心沒點逼數嗎?
簡書以及簡書 CEO 最好作出深入的道歉, 不然我也會離開簡書 (好像我更文頻率也不是很高把? 咳咳... 我主打的是質量! 質量! 不是數量, 逃~)
在實際項目中使用 ViewModel 組件 時我也遇到了一些問題, 浪費了我不少時間, 因此有必要分享出來讓你們少走彎路
Hello 我叫Jessyan,若是您喜歡個人文章,能夠在如下平臺關注我
-- The end