LiveData源碼分析

LiveData源碼分析

LiveData是Android提供的監聽數據更新的框架,它能夠感應Activity/Fragment的生命週期,接下來的內容我們來通過簡單的用法去探索LiveData源碼的核心知識點。

LiveData感應生命週期的核心

Android涉及到生命週期的時候,基本都是和Lifecycle類有關,我們先來看一下

**LiveData.observe(LifecycleOwner owner, @NonNull Observer<? super T> observer)**裏面的代碼:

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {

    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        // ignore
        return;
    }
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
   	...
    ...
    owner.getLifecycle().addObserver(wrapper);
}

Lifecycle是谷歌提供的用來監聽Activity與Fragment的生命週期變化,Lifecycle提供了兩個接口:

  • LifeCycleOwner 生命週期的擁有者,也就是Activity/Fragment,其Android源碼一般都繼承這個接口
  • LifeCycleObserver 生命週期的觀察者,可以是任何類,常見的有MVP的P

上面簡單的講解了Lifecycle的作用,回到上面那段代碼,我們可以看到,當檢測到當前是生命週期是DESTROYED的時候,直接忽略掉,不進行添加任何監聽器。

接下來我們再看看LifecycleBoundObserver類:

class LifecycleBoundObserver extends ObserverWrapper

LifecycleBoundObserver類是ObserverWrapper抽象類的子類:

private abstract class ObserverWrapper {
   	....
	// 是否激活狀態
    abstract boolean shouldBeActive();
	
    boolean isAttachedTo(LifecycleOwner owner) {
        return false;
    }
	//分離監聽
    void detachObserver() {
    }
	//激活狀態改變
    void activeStateChanged(boolean newActive) {
       ....
    }
}

可以看到,ObserverWrapper抽象類主要是定義了一些固定的規範,然後我們看看LifecycleBoundObserver類的代碼:

class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
    @NonNull
    final LifecycleOwner mOwner;

    LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
        super(observer);
        mOwner = owner;
    }
	
    @Override
    boolean shouldBeActive() {
		// 只有大於Start狀態纔是激活狀態
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }

    @Override
    public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
		// 當前是DESTROYED狀態的時候直接不處理,並刪除監聽
        if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        activeStateChanged(shouldBeActive());
    }

    @Override
    boolean isAttachedTo(LifecycleOwner owner) {
        return mOwner == owner;
    }

    @Override
    void detachObserver() {
		//移除監聽
        mOwner.getLifecycle().removeObserver(this);
    }
}

LifecycleBoundObserver是一個包裝類,是對LifeCycleOwnerLifeCycleObserver的組合。

所以我們總結一下:

LiveData是通過Lifecycle來感應生命週期的,當Activity/Fragment在Start和Destory之間時,纔會發送更新信息,否則不進行更新,想要更具體的理解這一塊內容,還是得往下看。

LiveData註冊監聽器

LiveData用監聽的處理分兩種:

  • 能夠感應生命週期
  • 不考慮感應生命週期

我們先來看看能夠感應生命週期的代碼段:

public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
	// 1.0檢測當前是否是主線程
    assertMainThread("observe");
	// 2.0當前是DESTROYED狀態,直接忽略
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        return;
    }
	// 3.0把生命週期擁有者和觀察者包裝起來
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
	// 4.0 以Map的結構添加包裝類,然後判斷是否已經添加過了,已經添加則拋出異常
    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;
    }
	// 5.0將監聽者添加到相應位置
    owner.getLifecycle().addObserver(wrapper);
}

總結流程如下:

  • 檢測當前是否是主線程
  • 當前是DESTROYED狀態,直接忽略
  • 把生命週期擁有者和觀察者包裝起來
  • 以Map的結構添加包裝類,然後判斷是否已經添加過了,已經添加則拋出異常
  • 將監聽者添加到相應位置

然後我們再看看不考慮感應生命週期的代碼段:

public void observeForever(@NonNull Observer<? super T> observer) {
    assertMainThread("observeForever");
    AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    if (existing != null && existing instanceof LiveData.LifecycleBoundObserver) {
        throw new IllegalArgumentException("Cannot add the same observer"
                + " with different lifecycles");
    }
    if (existing != null) {
        return;
    }
    wrapper.activeStateChanged(true);
}

可以看到不考慮感應生命週期的時候,基本流程和感應生命週期的一致,只是使用了不同的ObserverWrapper抽象類的包裝子類,我們來看看AlwaysActiveObserver的代碼:

private class AlwaysActiveObserver extends ObserverWrapper {

    AlwaysActiveObserver(Observer<? super T> observer) {
        super(observer);
    }

    @Override
    boolean shouldBeActive() {
        return true;
    }
}

AlwaysActiveObserver類中的激活狀態是永遠返回True的,那麼說明其永遠都是激活態。

LiveData發送更新數據信息

LiveData提供了兩個方法進行更新數據:

  • postValue:非主線程更新數據
  • setValue:必須在主線程才能更新數據,否則會拋出異常

我們先看看LiveData.postValue的代碼:

protected void postValue(T value) {
    boolean postTask;
	1.0 加鎖,並把value賦值給全局變量mPendingData
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        mPendingData = value;
    }
	2.0 判斷mPendingData是否已經完成之前的任務
    if (!postTask) {
        return;
    }
	3.0 切換到主線程執行任務
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

private final Runnable mPostValueRunnable = new Runnable() {
    @Override
    public void run() {
        Object newValue;
		4.0 把mPendingData全局變量賦值給局部變量,然後把mPendingData恢復初始狀態
        synchronized (mDataLock) {
            newValue = mPendingData;
            mPendingData = NOT_SET;
        }
		5.0 設置更新值
        setValue((T) newValue);
    }
};

從上面的代碼,我們可以總結出,LiveData.postValue主要是做了線程的切換工作,最終還是由LiveData.setValue來完成數據的更新提醒:

protected void setValue(T value) {
    assertMainThread("setValue");
	//版本+1
    mVersion++;
	// 全局變量保存需要更新的值
    mData = value;
    dispatchingValue(null);
}


void dispatchingValue(@Nullable ObserverWrapper initiator) {
    ...
    do {
        mDispatchInvalidated = false;
        if (initiator != null) {
			// 更新數據的通知
            considerNotify(initiator);
            initiator = null;
        } else {
            for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                considerNotify(iterator.next().getValue());
                ...
            }
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;
}


private void considerNotify(ObserverWrapper observer) {
	// 不是激活狀態不處理
    if (!observer.mActive) {
        return;
    }
    // 判斷是不處於激活狀態
    if (!observer.shouldBeActive()) {
		// 通知激活狀態改爲false
        observer.activeStateChanged(false);
        return;
    }
	// 監聽者的版本號大於當前的版本號不分發
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    observer.mLastVersion = mVersion;
    // 通知數據的更新
    observer.mObserver.onChanged((T) mData);
}

總結整個更新值通知的流程就是:

  1. 切換線程更新值
  2. 根據ObserverWrapper開發逐個監聽者分發
  3. 分發的時候要剔除不是激活態的和老版本的不分發
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章