Android源碼進(jìn)階之LiveData工作原理詳解
本文轉(zhuǎn)載自微信公眾號(hào)「Android開發(fā)編程」,作者Android開發(fā)編程。轉(zhuǎn)載本文請(qǐng)聯(lián)系A(chǔ)ndroid開發(fā)編程公眾號(hào)。
前言
LiveData 是一種可觀察的數(shù)據(jù)存儲(chǔ)器類。與常規(guī)的可觀察類不同,LiveData 具有生命周期感知能力,意指它遵循其他應(yīng)用組件(如 Activity、Fragment 或 Service)的生命周期。
這種感知能力可確保 LiveData 僅更新處于活躍生命周期狀態(tài)的應(yīng)用組件觀察者。
LiveData本身是觀察者,觀察組件的Lifecycle,也是被觀察者,數(shù)據(jù)變化時(shí)要通知數(shù)據(jù)的觀察者。
前面我們講解了Lifecycle實(shí)現(xiàn)原理,今天我們來(lái)看LiveData
源碼進(jìn)階之lifecycle組件原理分析
一、livedata的在app中的應(yīng)用
1、使用livedata的步驟
- 創(chuàng)建一個(gè)實(shí)例LiveData來(lái)保存某種類型的數(shù)據(jù)。這通常在你的ViewModel類內(nèi)完成;
- 創(chuàng)建一個(gè)Observer 定義onChanged()方法的對(duì)象,該對(duì)象 控制LiveData對(duì)象保存的數(shù)據(jù)更改時(shí)發(fā)生的情況。您通常Observer在UI控制器中創(chuàng)建對(duì)象,例如activity或fragment;
- 使用該 方法將Observer對(duì)象附加到對(duì)象。該方法需要一個(gè)對(duì)象。這將對(duì)象訂閱到對(duì)象,以便通知其更改。您通常將該對(duì)象附加到UI控制器中,例如活動(dòng)或片段;
2、livedata的簡(jiǎn)單例子
在viewModel中之定義live data
- public class NameViewModel extends ViewModel {
- // Create a LiveData with a String
- private MutableLiveData<String> mCurrentName;
- public MutableLiveData<String> getCurrentName() {
- if (mCurrentName == null) {
- mCurrentName = new MutableLiveData<String>();
- }
- return mCurrentName;
- }
- // Rest of the ViewModel...
- }
在activity或者Fragment中實(shí)施監(jiān)聽來(lái)更新ui
- public class NameActivity extends AppCompatActivity {
- private NameViewModel mModel;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // Other code to setup the activity...
- // Get the ViewModel.
- mModel = ViewModelProviders.of(this).get(NameViewModel.class);
- // Create the observer which updates the UI.
- final Observer<String> nameObserver = new Observer<String>() {
- @Override
- public void onChanged(@Nullable final String newName) {
- // Update the UI, in this case, a TextView.
- mNameTextView.setText(newName);
- //注意這里 在MVVM 中不是這樣寫的 這里只是單行綁定
- }
- };
- // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
- mModel.getCurrentName().observe(this, nameObserver);
- //注意這個(gè)地方用沒有用Java8的lambda表達(dá)式,可以寫的更加簡(jiǎn)練,
- }
- }
更新livedata對(duì)象
調(diào)用setValue(T)示例會(huì)導(dǎo)致觀察者onChanged()使用該值調(diào)用其ui進(jìn)行刷新。該示例示出了按鈕按下,但setValue()還是postValue()可以被調(diào)用以更新mName為各種各樣的原因,包括響應(yīng)于網(wǎng)絡(luò)請(qǐng)求或數(shù)據(jù)庫(kù)負(fù)荷完成; 在所有情況下,呼叫setValue()或postValue()觸發(fā)觀察員并更新UI;
- mButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- String anotherName = "John Doe";
- mModel.getCurrentName().setValue(anotherName);
- }
- });
- mButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- String anotherName = "John Doe";
- mModel.getCurrentName().setValue(anotherName);
- }
- });
二、livedata原理詳細(xì)分析
1、observe 方法
- 首先這個(gè)方法只能在主線程注冊(cè)觀察;
- 官方文檔說LiveData僅處于活躍生命周期才有效,所以一開始就開始判斷是否為 Lifecycle.Stete.DESTROYED,是的話就沒有然后了,直接return;
- 接下來(lái)就是 創(chuàng)建 LifecycleBoundObserver ,生命周期變化邏輯在這里面;
- 然后就是最后一行注冊(cè)觀察,如果想了解 Lifecycle.addObserver 做了什么可以看 Android Lifecycle實(shí)現(xiàn)原理;
- //map 的 key 為L(zhǎng)iveData數(shù)據(jù)觀察者,value為組件的Lifecycle觀察者
- private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
- new SafeIterableMap<>();
- @MainThread
- public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
- assertMainThread("observe");
- //判斷當(dāng)前生命周期的狀態(tài)
- if (owner.getLifecycle().getCurrentState() == DESTROYED) {
- // ignore
- return;
- }
- //Lifecycle的生命周期變化邏輯在這里
- LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
- //mObservers 保存
- ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
- if (existing != null && !existing.isAttachedTo(owner)) {
- throw new IllegalArgumentException("Cannot add the same observer"
- + " with different lifecycles");
- }
- if (existing != null) {
- return;
- }
- //感知lifecycle的生命周期變化
- owner.getLifecycle().addObserver(wrapper);
- }
2、LifecycleBoundObserver
- LifecycleBoundObserver 繼承 ObserverWrapper ,實(shí)現(xiàn) LifecycleEventObserver 接口。
- ObserverWrapper 用于判斷組件當(dāng)前是否活躍;
- LifecycleEventObserver 就是 Lifecycle 的觀察者了,重寫了 onStateChanged 方法,當(dāng)Lifecycle 生命周期發(fā)生變化時(shí),就會(huì)在此方法接收到,LiveData 也就能感知到,如果組件的生命周期是 DESTROYED ,那也就移除觀察;
- 到這里 LiveData 對(duì)組件的生命周期感知就注冊(cè)完成了,可以開始發(fā)送數(shù)據(jù);
- class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
- @NonNull
- //一般組件,比如Activity、fragment可以會(huì)實(shí)現(xiàn)LifecycleOwner ,可以拿到lifecycle
- final LifecycleOwner mOwner;
- LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
- super(observer);
- mOwner = owner;
- }
- /* 判斷當(dāng)前組件當(dāng)前是否活躍 */
- @Override
- boolean shouldBeActive() {
- return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
- }
- @Override
- public void onStateChanged(@NonNull LifecycleOwner source,
- @NonNull Lifecycle.Event event) {
- //獲取當(dāng)前生命周期狀態(tài)
- Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
- //如果組件已銷毀了,就移除觀察
- if (currentState == DESTROYED) {
- removeObserver(mObserver);
- return;
- }
- Lifecycle.State prevState = null;
- while (prevState != currentState) {
- prevState = currentState;
- activeStateChanged(shouldBeActive());
- currentState = mOwner.getLifecycle().getCurrentState();
- }
- }
- /* 判斷是否綁定 */
- @Override
- boolean isAttachedTo(LifecycleOwner owner) {
- return mOwner == owner;
- }
- /* 移除觀察 */
- @Override
- void detachObserver() {
- mOwner.getLifecycle().removeObserver(this);
- }
- }
3、activeStateChanged
ObserverWrapper 這個(gè)類里面有個(gè)方法,后面的粘性事件會(huì)用到;
- void activeStateChanged(boolean newActive) {
- //組件狀態(tài)如果不變返回
- if (newActive == mActive) {
- return;
- }
- // immediately set active state, so we'd never dispatch anything to inactive
- // owner
- mActive = newActive;
- changeActiveCounter(mActive ? 1 : -1);
- //如果是活動(dòng)的就發(fā)送數(shù)據(jù)
- if (mActive) {
- dispatchingValue(this);
- }
- }
4、發(fā)送數(shù)據(jù)分析
4.1、postValue 發(fā)送數(shù)據(jù)到主線程
這個(gè)方法最核心的就是利用主線程Handler發(fā)送數(shù)據(jù),一步步拆開分析;
- protected void postValue(T value) {
- boolean postTask;
- //加鎖
- synchronized (mDataLock) {
- postTask = mPendingData == NOT_SET;
- //保存要發(fā)送的數(shù)據(jù)value
- mPendingData = value;
- }
- if (!postTask) {
- return;
- }
- //利用主線程Handler發(fā)送
- ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
- }
4.2、postValue 其實(shí)就是 setValue
在postValue 要發(fā)送的 Runnable ,可以看到最后一行就是 setValue 方法,數(shù)據(jù)也即是之前保存的mPendingData ,只是在這又給 newValue;
- private final Runnable mPostValueRunnable = new Runnable() {
- @SuppressWarnings("unchecked")
- @Override
- public void run() {
- Object newValue;
- synchronized (mDataLock) {
- newValue = mPendingData;
- mPendingData = NOT_SET;
- }
- setValue((T) newValue);
- }
- };
4.3、postToMainThread 主線程Handler
ArchTaskExecutor 類 postToMainThread 方法,實(shí)際就是 DefaultTaskExecutor 類執(zhí)行 postToMainThread 方法;
- public class ArchTaskExecutor extends TaskExecutor {
- @NonNull
- private TaskExecutor mDelegate;
- @NonNull
- private TaskExecutor mDefaultTaskExecutor;
- private ArchTaskExecutor() {
- mDefaultTaskExecutor = new DefaultTaskExecutor();
- mDelegate = mDefaultTaskExecutor;
- }
- ...
- @Override
- public void postToMainThread(Runnable runnable) {
- mDelegate.postToMainThread(runnable);
- }
- ...
- }
4.4、DefaultTaskExecutor類
我們知道是 DefaultTaskExecutor. postToMainThread,就直接看這個(gè)方法,哎呀,太熟悉的代碼,創(chuàng)建 Handler ,傳入的是 Looper.getMainLooper() ,就是主線程Handler ,然后就 post 消息;
- public class DefaultTaskExecutor extends TaskExecutor {
- @Nullable
- private volatile Handler mMainHandler;
- @Override
- public void postToMainThread(Runnable runnable) {
- if (mMainHandler == null) {
- synchronized (mLock) {
- if (mMainHandler == null) {
- mMainHandler = createAsync(Looper.getMainLooper());
- }
- }
- }
- //noinspection ConstantConditions
- mMainHandler.post(runnable);
- }
- }
4.5、setValue 方法
mVersion 在初始化的構(gòu)造方法里就賦值了,為-1,每次setValue,版本號(hào)就會(huì)變一次;
setValue 也就是用 mData 保存一下 value ,然后交給 dispatchingValue 方法處理;
- @MainThread
- protected void setValue(T value) {
- assertMainThread("setValue");
- mVersion++;
- mData = value;
- dispatchingValue(null);
- }
4.6、dispatchingValue 方法
setValue走該方法,傳的 initiator為空,那就遍歷 mObservers 保存的觀察者發(fā)送數(shù)據(jù);
- @SuppressWarnings("WeakerAccess") /* synthetic access */
- void dispatchingValue(@Nullable ObserverWrapper initiator) {
- if (mDispatchingValue) {
- mDispatchInvalidated = true;
- return;
- }
- mDispatchingValue = true;
- do {
- mDispatchInvalidated = false;
- if (initiator != null) {
- //粘性事件,就單個(gè)觀察者接受數(shù)據(jù)
- considerNotify(initiator);
- initiator = null;
- } else {
- //setvalue 傳過來(lái) initiator 為空,執(zhí)行這里
- // mObservers 拿出來(lái),逐個(gè)發(fā)送數(shù)據(jù)
- for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
- mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
- considerNotify(iterator.next().getValue());
- if (mDispatchInvalidated) {
- break;
- }
- }
- }
- } while (mDispatchInvalidated);
- mDispatchingValue = false;
- }
4.7、considerNotify 判斷發(fā)送數(shù)據(jù)
- 這里先判斷組件是否活動(dòng)
- 在判斷粘性事件
- 然后用 mVersion ,判斷是否發(fā)送過數(shù)據(jù)
- 最后才是給觀察者發(fā)送數(shù)據(jù)
- private void considerNotify(ObserverWrapper observer) {
- //組件是否活動(dòng)
- if (!observer.mActive) {
- return;
- }
- // Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
- //
- // we still first check observer.active to keep it as the entrance for events. So even if
- // the observer moved to an active state, if we've not received that event, we better not
- // notify for a more predictable notification order.
- //判斷粘性事件
- if (!observer.shouldBeActive()) {
- observer.activeStateChanged(false);
- return;
- }
- //校驗(yàn)是否發(fā)送過數(shù)據(jù)
- if (observer.mLastVersion >= mVersion) {
- return;
- }
- observer.mLastVersion = mVersion;
- //發(fā)送數(shù)據(jù)
- observer.mObserver.onChanged((T) mData);
- }
5、粘性事件分析
- 粘性事件就是先發(fā)送數(shù)據(jù),后面再注冊(cè)觀察者,還能收到消息;
- 我們就從LiveData.observe 開始,新的頁(yè)面注冊(cè)LiveData觀察者,也注冊(cè)Lifecycle觀察;
- 當(dāng)新頁(yè)面生命周期變化,就會(huì)執(zhí)行 LifecycleBoundObserver.onStateChanged 的方法;
- 接下來(lái) activeStateChanged 方法,因?yàn)槭切马?yè)面,組件狀態(tài)是活動(dòng)的,就走到 dispatchingValue 方法;
- dispatchingValue 傳進(jìn)來(lái)當(dāng)前新頁(yè)面的 initiator 是不為空的,就只會(huì)給當(dāng)前觀察者發(fā)送數(shù)據(jù);
總結(jié):
1、LifecycleOwner生命周期從非活躍變成活躍狀態(tài)時(shí):
Livedata添加一個(gè)觀察者時(shí),會(huì)關(guān)聯(lián)一個(gè)LifecycleOwner,然后把這個(gè)觀察者包裝成一個(gè)LifecycleBoundObserver,和LifecycleOwner的getLifecycle關(guān)聯(lián),當(dāng)LifecycleBoundObserver的生命周期變化時(shí),會(huì)調(diào)用LifecycleBoundObserver的onStateChanged方法,在這個(gè)方法中判斷當(dāng)前生命周期和上次的生命周期是否是同一類型(要么活躍要么非活躍),如果是,就直接返回,避免重復(fù)通知(start通知了,resume就不需要通知了),如果不是同一類型,并且當(dāng)前生命周期是活躍狀態(tài),就調(diào)用dispatchingValue方法通知觀察者,判斷LifecycleOwner是否時(shí)活躍狀態(tài),如果是,將Livedata中持有的最新更新給觀察者;
2、Livedata中的值改變時(shí):
同樣是調(diào)用dispatchingValue,判斷LifecycleOwner是否時(shí)活躍狀態(tài),如果是,就遍歷通知所有觀察者;