阿里P7移動互聯網架構師進階視頻(每日更新中)免費學習請點擊:https://space.bilibili.com/474380680
前言
本篇文章主要講解LiveData工作的原理,如果還不知道LiveData如何用的話,請參考官方文檔。
LiveData的講解涉及到了Lifecycle的知識,如果你還不了解LifeCycle,請參考文檔LifeCycle介紹。
介紹
LiveData是一個數據持有類,它可以通過添加觀察者被其他組件觀察其變更。不同於普通的觀察者,它最重要的特性就是遵從應用程序的生命周期,如在Activity中如果數據更新了但Activity已經是destroy狀態,LivaeData就不會通知Activity(observer)。當然。LiveData的優點還有很多,如不會造成內存泄漏等。
LiveData通常會配合ViewModel來使用,ViewModel負責觸發數據的更新,更新會通知到LiveData,然后LiveData再通知活躍狀態的觀察者。
原理分析
下面直接看代碼:
上面UserProfileViewModel內部持有 UserRepository 中 MutableLiveData<User>的引用,並且提供了獲取 MutableLiveData 的方法 getUser(),UserRepository 負責從網絡或數據庫中獲取數據並封裝成 MutableLiveData 然后提供給 ViewModel。
我們在 UserProfileFragment 中為 MutableLiveData<User> 注冊觀察者,如下:
看標注1處,viewModel.getUser()獲取到 MutableLiveData<User> 也就是我們的 LiveData,然后調用 LiveData的observer方法,並把UserProfileFragment作為參數傳遞進去。observer() 方法就是我們分析的入口了,接下來我們看LiveData的observer()方法都做了什么:
可以看到,UserProfileFragment 是作為 LifeCycleOwner 參數傳進來的,如果你的support包版本大於等於26.1.0,support包中的 Fragment 會默認繼承自 LifecycleOwner,而 LifecycleOwner 可獲取到該組件的 LifeCycle,也就知道了 UserProfileFragment 組件的生命周期(在這里默認大家已經了解過LifeCycle了)。
看標注1處,如果我們的 UserProfileFragment 組件已經是destroy狀態的話,將直接返回,不會被加入觀察者行列。如果不是destroy狀態,就到標注2處,新建一個 LifecycleBoundObserver 將我們的 LifecycleOwner 和 observer保存起來,然后調用 mObservers.putIfAbsent(observer, wrapper) 將observer和wrapper分別作為key和value存入Map中,putIfAbsent()方法會判斷如果 value 已經能夠存在,就返回,否則返回null。
如果返回existing為null,說明以前沒有添加過這個觀察者,就將 LifecycleBoundObserver 作為 owner 生命周期的觀察者,也就是作為 UserProfileFragment 生命周期的觀察者。
我們看下LifecycleBoundObserver 源碼:
代碼並不多,LifecycleBoundObserver 繼承自 ObserverWrapper 並實現了 GenericLifecycleObserver接口,而 GenericLifecycleObserver 接口又繼承自 LifecycleObserver 接口,那么根據 Lifecycle 的特性,實現了LifecycleObserver接口並且加入 LifecycleOwner 的觀察者里就可以感知或主動獲取 LifecycleOwner 的狀態。
好了,看完了觀察者,那么我們的LiveData什么時候會通知觀察者呢?不用想,肯定是數據更新的時候,而數據的更新是我們代碼自己控制的,如請求網絡返回User信息后,我們會主動將User放入MutableLiveData中,這里我在UserRepository中直接模擬網絡請求如下:
當調用getUser()方法的時候,我們調用MutableLiveData的setValue()方法將數據放入LiveData中,這里MutableLiveData實際上就是繼承自LiveData,沒有什么特別:
setValue()在放入User的時候必須在主線程,否則會報錯,而postValue則沒有這個檢查,而是會把數據傳入到主線程。我們直接看setValue()方法:
首先調用assertMainThread()檢查是否在主線程,接着將要更新的數據賦給mData,然后調用 dispatchingValue()方法並傳入null,將數據分發給各個觀察者,如我們的 UserProfileFragment。看 dispatchingValue()方法實現:
從標注1可以看出,dispatchingValue()參數傳null和不傳null的區別就是如果傳null將會通知所有的觀察者,反之僅僅通知傳入的觀察者。我們直接看標注2,通知所有的觀察者通過遍歷 mObservers ,將所有的 ObserverWrapper 拿到,實際上就是我們上面提到的 LifecycleBoundObserver,通知觀察者調用considerNotify()方法,這個方法就是通知的具體實現了。
如果觀察者不是活躍狀態,將不會通知此觀察者,看最后一行,observer.mObserver.onChanged((T) mData),observer.mObserver就是我們調用LiveData的observer()方法傳入的 Observer,然后調用 Observer 的 onChanged((T) mData)方法,將保存的數據mData傳入,也就實現了更新。在看下我們實現的Observer:
如果哪個控件要根據user的變更而及時更新,就在onChanged()方法里處理就可以了。到這里,LiveData已經能夠分析完了,其實LiveData的實現還是要依賴於Lifecycle。
原文鏈接:https://www.jianshu.com/p/21bb6c0f8a5a
阿里P7移動互聯網架構師進階視頻(每日更新中)免費學習請點擊:https://space.bilibili.com/474380680