理解響應式編程,來一波LiveData的深入解析

/   開始   /

 

本文章主要是對LiveData進行源碼分析,本文章使用的是Android SDK 29的源碼分析。

 

/   定義   /

 

LiveData是一種可觀察的數據存儲器類,它具有生命週期感知能力,遵循應用組件(例如:Activity、Fragment、Service(可以使用LifecycleService,它是實現了LifecycleOwner接口的Service))的生命週期,這種感知能力確保LiveData僅更新處於活躍生命週期狀態的應用組件觀察者。

 

如果觀察者(由Observer類表示)的生命週期處於STARTED或者RESUMED狀態,那麼LiveData會認爲該觀察者處於活躍狀態,就會將更新通知它,而那些觀察LiveData對象而註冊的非活躍觀察者不會收到更改通知。

 

應用組件都實現了LifecycleOwner接口,有了這種關係後,當相應的Lifecycle對象的狀態變爲DESTROYED時,就會移除這些觀察者。

 

使用LiveData的優勢:

 

確保界面符合數據狀態

 

LiveData遵循觀察者模式,當生命週期狀態發生變化的時候,它就會去通知Observer對象,然後去更新界面。

 

不會發生內存泄露

 

當應用組件的生命週期處於DESTROYED狀態時,就會移除這些觀察者,使其不再持有應用組件的引用。

 

不會因Activity停止而導致崩潰

 

如果觀察者的生命週期處於非活躍狀態(例如:返回棧中的Actvity),則它不會接受任何LiveData的事件。

 

不再需要手動處理生命週期

 

界面組件只是觀察相關數據,不會停止或恢復觀察,LiveData將自動管理所有這些操作,因爲它在觀察的時候可以感知相關的生命週期狀態變化。

 

數據始終保持最新狀態

 

如果生命週期變爲非活躍狀態,它會在再次變爲活躍狀態時接收最新的數據,例如:曾經在後臺的Activity會在返回前臺後立即接收最新的數據。

 

適當的配置更改

 

如果由於配置更改(例如:設備旋轉)而重新創建了Activity或者Fragment,它會立即接收到最新的數據。

 

共享資源

 

我們可以使用單例模式繼承LiveData以封裝相關業務邏輯,以便在應用中共享它們。

 

/   使用LiveData   /

 

使用步驟如下:

 

  1. 通常是在ViewModel中創建LiveData實例以存儲某種類型的數據。

  2. 創建Observer對象,並且實現它的onChanged方法,這個方法可以控制當LiveData對象存儲的數據發生更改時要處理什麼。

  3. 在大多數情況下,會在應用組件的onCreate方法觀察LiveData對象,調用LiveData對象的observer方法,有兩個參數,第一個參數是LifecycleOwner,它是一個接口,Activity、Fragment、LifecycleService都實現了這個接口,第二個參數是第二步創建的Observer對象,這樣就可以使Observer對象訂閱LiveData對象,以使其收到有關更改的通知。

 

注意:請確保用於更新界面的LiveData對象存儲在ViewModel對象中,而不是將其存儲在Activity或者Fragment中,原因如下:

 

  1. 避免Activity或者Fragment過於龐大,因爲這些界面控制器只負責顯示數據,不負責存儲數據狀態。

  2. 將LiveData實例與Activity和Fragment分離開,可以使它在配置更改後繼續存在。

 

/   示例代碼   /

 

項目添加如下依賴:

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-alpha02'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0-rc03'

由於我這邊用到了DataBinding,所以加上如下代碼:

dataBinding {
    enabled = true
}

 

項目結構如下圖:

 

定義MainViewModel,並且繼承ViewModel,在該類中創建兩個MutableLiveData,firstContent是爲了演示在主線程更新LiveData對象,secondContent是爲了演示在工作線程更新LiveData對象,代碼如下:

/**
 * Created by TanJiaJun on 2019-12-22.
 */
class MainViewModel : ViewModel() {

    private val _firstContent = MutableLiveData<String>().apply {
        value = "第一個文本"
    }
    val firstContent: LiveData<String> = _firstContent

    private val _secondContent = MutableLiveData<String>().apply {
        value = "第二個文本"
    }
    val secondContent: LiveData<String> = _secondContent

    // 在主線程更新LiveData對象,調用了MutableLiveData的setValue方法,下面會分析
    fun changeFirstContent(text: String) {
        _firstContent.value = text
    }

    // 在工作線程更新LiveData對象,調用了MutableLiveData的postValue方法,下面會分析
    fun changeSecondContent(text: String) =
        viewModelScope.launch {
            withContext(Dispatchers.Default) {
                _secondContent.postValue(text)
            }
        }

}

 

定義FirstFragment,代碼如下:

/**
 * Created by TanJiaJun on 2019-12-22.
 */
class SecondFragment : Fragment(), SecondHandlers {

    private var viewModel: MainViewModel? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewModel = activity?.let { ViewModelProviders.of(it)[MainViewModel::class.java] }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? =
        DataBindingUtil.inflate<FragmentSecondBinding>(
            inflater,
            R.layout.fragment_second,
            container,
            false
        )
            .also {
                it.handlers = this
            }
            .root

    // 點擊第一個Button調用MainViewModel中的changeFirstContent方法,使FirstFragment中的第一個TextView的文本從”第一個文本“變成”第一個文本已改變“
    override fun onChangeFirstContentClick(view: View) {
        viewModel?.changeFirstContent(getString(R.string.first_content_changed))
    }

    // 點擊第二個Button調用MainViewModel中的changeSecondContent方法,使FirstFragment中的第二個TextView的文本從”第二個文本“變爲”第二個文本已改變“
    override fun onChangeSecondContentClick(view: View) {
        viewModel?.changeSecondContent(getString(R.string.second_content_changed))
    }

}

interface SecondHandlers {

    fun onChangeFirstContentClick(view: View)

    fun onChangeSecondContentClick(view: View)

}

由於我這裏還同時用到了DataBinding、ViewModel、Kotlin協程,所以我會在下面先按照官方文檔的寫法進行源碼分析。

 

/   源碼分析   /

 

LiveData是一個抽象類,我們常用的主要用到MutableLiveData和MediatorLiveData這兩個子類,我們先看下LiveData的結構圖:

 

 

我們看下幾個常用的方法,先看下observer方法,observer方法是用於在指定的LifecycleOwner內將指定的觀察者添加到觀察列表中,代碼如下:

// LiveData.java
// 創建key爲Observer,value爲ObserverWrapper的Map
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
            new SafeIterableMap<>();

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    // 檢查是否在主線程,如果不在主線程就會拋出異常
    assertMainThread("observe");
    // 判斷LifecycleOwner是否處於DESTROYED狀態
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        // 如果是就return,不再分發
        return;
    }
    // 創建LifecycleBoundObserver,對傳入的LifecycleOwner和Observer進行包裝,下面會分析這個類
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    // 把LifecycleBoundObserver存儲到SafeIterableMap,key爲Observer,value爲ObserverWrapper,如果是第一次存儲這個Observer,就會返回null
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    // 第一個條件是判斷是否第一次存儲這個Observer,第二個條件是判斷這個Observer是否已經附在到LifecycleOwner
    if (existing != null && !existing.isAttachedTo(owner)) {
        // 如果不是第一次存儲這個Observer,而且已經附在到LifecycleOwner,拋出“不能添加附加到不同的生命週期,但是是相同的Observer
        throw new IllegalArgumentException("Cannot add the same observer"
                + " with different lifecycles");
    }
    // 再次判斷是否第一次存儲這個Observer
    if (existing != null) {
        // 如果不是第一次存儲這個Observer就return
        return;
    }
    // 調用Lifecycle的addObserver方法
    owner.getLifecycle().addObserver(wrapper);
}

 

SafeIterableMap是個Map,它實際上是個LinkedList,並且支持在迭代期間修改,但是不是線程安全,LiveData用它來存儲LifecycleBoundObserver。

 

Lifecycle是一個抽象類,它的唯一子類是LifecycleRegistry,我們看下它的addObserver方法,代碼如下:

// LifecycleRegistry.java
// 創建key爲LifecycleObserver,value爲ObserverWithState的FastSafeIterableMap
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
            new FastSafeIterableMap<>();

// 擁有此生命週期的提供者,在LifecycleOwner上只保留弱引用,所以如果有人泄露了Lifecycle對象,它們不會泄露整個Activity或者Fragment,但是這樣做也會泄露所有Listener對象,因爲在所有Listener對象上保持着強引用
private final WeakReference<LifecycleOwner> mLifecycleOwner;

public LifecycleRegistry(@NonNull LifecycleOwner provider) {
    mLifecycleOwner = new WeakReference<>(provider);
    mState = INITIALIZED;
}

@Override
public void addObserver(@NonNull LifecycleObserver observer) {
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    // 將LifecycleObserver(我們傳入的是LifecycleBoundObserver)和State包裝成ObserverWithState
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    // 把ObserverWithState存儲到FastSafeIterableMap,key爲LifecycleBoundObserver,value爲ObserverWithState,如果是第一次存儲這個ObserverWithState,就會返回null
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

    // 判斷是否第一次存儲這個ObserverWithState
    if (previous != null) {
        // 如果不是第一次存儲這個ObserverWithState就return
        return;
    }
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    // 判斷LifecycleOwner是不是null
    if (lifecycleOwner == null) {
        // 如果是null的話,應該立刻被銷燬,快速回退
        return;
    }

    boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
    State targetState = calculateTargetState(observer);
    mAddingObserverCounter++;
    while ((statefulObserver.mState.compareTo(targetState) < 0
            && mObserverMap.contains(observer))) {
        pushParentState(statefulObserver.mState);
        statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
        popParentState();
        // mState或者subling可能被重新計算
        targetState = calculateTargetState(observer);
    }

    // 判斷是不是在堆棧的頂層
    if (!isReentrance) {
        // 如果是在堆棧的頂層就執行同步
        sync();
    }
    mAddingObserverCounter--;
}

如果是在堆棧的頂層,就會調用sync方法,因此也不會在重入的時候調用這個方法,我們看下這個方法,代碼如下:

// LifecycleRegistry.java
private void sync() {
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    // 判斷LifecycleOwner是不是null
    if (lifecycleOwner == null) {
        // 如果是null的話,拋出異常,證明這個LifecycleRegistry的LifecycleOwner已經被垃圾回收了,改變生命週期太遲了
        throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
                + "garbage collected. It is too late to change lifecycle state.");
    }
    while (!isSynced()) {
        mNewEventOccurred = false;
        // 不需要檢查eldest是不是null,因爲isSynced已經幫我們判斷了
        if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
            // 如果ObserverWithState的state小於當前的state,就會倒序遍歷改變狀態同時通知觀察者
            backwardPass(lifecycleOwner);
        }
        Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > 0) {
            // 如果ObserverWithState的state大於當前的state,就會正序遍歷改變狀態同時通知觀察者
            forwardPass(lifecycleOwner);
        }
    }
    mNewEventOccurred = false;
}

我們看下forwardPass方法和backwardPass方法,代碼如下:

// LifecycleRegistry.java
// 正序遍歷改變狀態同時通知觀察者
private void forwardPass(LifecycleOwner lifecycleOwner) {
    Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
            mObserverMap.iteratorWithAdditions();
    // 正序遍歷mObserverMap
    while (ascendingIterator.hasNext() && !mNewEventOccurred) {
        Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
        ObserverWithState observer = entry.getValue();
        while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            pushParentState(observer.mState);
            // 調用ObserverWithState的dispatchEvent方法
            observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
            popParentState();
        }
    }
}

// 倒序遍歷改變狀態同時通知觀察者
private void backwardPass(LifecycleOwner lifecycleOwner) {
    Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
            mObserverMap.descendingIterator();
    // 倒序遍歷mObserverMap
    while (descendingIterator.hasNext() && !mNewEventOccurred) {
        Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
        ObserverWithState observer = entry.getValue();
        while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            Event event = downEvent(observer.mState);
            pushParentState(getStateAfter(event));
            // 調用ObserverWithState的dispatchEvent方法
            observer.dispatchEvent(lifecycleOwner, event);
            popParentState();
        }
    }
}

 

ObserverWithState是LifecycleRegistry的靜態內部類,我們看下ObserverWithState的dispatchEvent方法,代碼如下:

// LifecycleRegistry.java
static class ObserverWithState {
    State mState;
    LifecycleEventObserver mLifecycleObserver;

    ObserverWithState(LifecycleObserver observer, State initialState) {
        // mLifecycleObserver爲LifecycleBoundObserver
        mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
        mState = initialState;
    }

    void dispatchEvent(LifecycleOwner owner, Event event) {
        State newState = getStateAfter(event);
        mState = min(mState, newState);
        // 調用LifecycleBoundObserver的onStateChanged方法
        mLifecycleObserver.onStateChanged(owner, event);
        mState = newState;
    }
}

 

LifecycleBoundObserver爲LiveData的內部類,我們看下onStateChanged方法,代碼如下:

// LiveData.java
// 這個方法判斷Lifecycle的狀態的值是否大於或等於STARTED狀態的值,從而判斷是否是活躍狀態
@Override
boolean shouldBeActive() {
    return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}

@Override
public void onStateChanged(@NonNull LifecycleOwner source,
        @NonNull Lifecycle.Event event) {
    // 判斷Lifecycle是否爲DESTROYED狀態
    if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
        // 如果Lifecycle是DESTROYED狀態,移除觀察者,並且return,下面會對removeObserver方法分析
        removeObserver(mObserver);
        return;
    }
    // 如果Lifecycle不是DESTROYED狀態,調用activeStateChanged方法,並且傳入shouldBeActive方法得到的布爾值
    activeStateChanged(shouldBeActive());
}

 

State是個枚舉,代碼如下:

@SuppressWarnings("WeakerAccess")
public enum State {

    DESTROYED,

    INITIALIZED,

    CREATED,

    STARTED,

    RESUMED;

    // 判斷當前state的值是否大於或等於傳入的state的值
    public boolean isAtLeast(@NonNull State state) {
        return compareTo(state) >= 0;
    }
}

我們可以看到,大於或等於STARTED的值就只有STARTED和RESUMED這兩個值了,也就是說這個方法是判斷是否爲活躍狀態。

 

activeStateChanged方法代碼如下:

// LiveData.java
void activeStateChanged(boolean newActive) {
    // 判斷狀態是否發生變化
    if (newActive == mActive) {
        // 如果沒有發生變化就return
        return;
    }
    // 如果有發生變化,立刻設置狀態,這樣就不會向不活躍的觀察者發送內容
    mActive = newActive;
    boolean wasInactive = LiveData.this.mActiveCount == 0;
    // 如果當前狀態是活躍狀態就會加1,否則就會減1
    LiveData.this.mActiveCount += mActive ? 1 : -1;
    if (wasInactive && mActive) {
        // 如果mActiveCount從0變成1,同時當前狀態屬於活躍狀態,就會調用onActive方法
        onActive();
    }
    if (LiveData.this.mActiveCount == 0 && !mActive) {
        // 如果mActiveCount從1變成0,同時當前狀態屬於不活躍狀態,就會調用onInactive
        onInactive();
    }
    if (mActive) {
        // 如果當前狀態是活躍狀態,調用dispatchingValue,並且傳入LifecycleBoundObserver
        dispatchingValue(this);
    }
}

 

我們看下dispatchingValue方法,代碼如下:

// LiveData.java
@SuppressWarnings("WeakerAccess") /* synthetic access */
void dispatchingValue(@Nullable ObserverWrapper initiator) {
    // 判斷是否正在分發
    if (mDispatchingValue) {
        // 如果正在分發,將mDispatchInvalidated設爲true,也就是設爲分發無效,並且return
        mDispatchInvalidated = true;
        return;
    }
    // 正在分發
    mDispatchingValue = true;
    do {
        mDispatchInvalidated = false;
        // 判斷initiator是否爲null,根據上面的代碼可知,這裏不爲null,注意一下爲null的邏輯,下面在說setValue、postValue、getValue的時候會涉及到
        if (initiator != null) {
            // 如果initiator不爲null就會調用considerNotify方法,傳入LifecycleBoundObserver
            considerNotify(initiator);
            initiator = null;
        } else {
            // 如果initiator爲null就會遍歷mObservers
            for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                // 調用considerNotify方法
                considerNotify(iterator.next().getValue());
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    // 分發完畢
    mDispatchingValue = false;
}

mDispatchingValue和mDispatchInvalidated這兩個變量是爲了防止重複分發相同的內容。

 

considerNotify方法代碼如下:

// LiveData.java
@SuppressWarnings("unchecked")
private void considerNotify(ObserverWrapper observer) {
    // 判斷是否爲活躍狀態
    if (!observer.mActive) {
        // 如果不是活躍狀態就return
        return;
    }
    // 在分發之前再檢查下最新的狀態是否爲活躍狀態,防止出現改變了狀態,但是我們還沒收到事件這種情況
    if (!observer.shouldBeActive()) {
        // 如果不是活躍狀態就通知不再分發
        observer.activeStateChanged(false);
        return;
    }
    // 判斷是否爲最新的數據
    if (observer.mLastVersion >= mVersion) {
        // 如果是最新的數據就不再分發
        return;
    }
    // 將版本設爲最新的版本
    observer.mLastVersion = mVersion;
    // 調用onChanged方法
    observer.mObserver.onChanged((T) mData);
}

 

onChanged方法的代碼如下:

// Observer.java
public interface Observer<T> {
    void onChanged(T t);
}

 

onChanged方法就是我們需要實現的方法,我們可以在這個方法實現數據發生變化的時候要執行的邏輯。

 

大家還記得sync這個方法嗎?如果忘記了,可以再往上面看下,這個sync方法也會被moveToState方法調用,代碼如下:

// LifecycleRegistry.java
private void moveToState(State next) {
    if (mState == next) {
        return;
    }
    mState = next;
    // 判斷是否在同步或者是否在添加觀察者
    if (mHandlingEvent || mAddingObserverCounter != 0) {
        mNewEventOccurred = true;
        // we will figure out what to do on upper level.
        // 如果正在同步或者正在添加觀察者就return
        return;
    }
    mHandlingEvent = true;
    // 調用sync方法
    sync();
    mHandlingEvent = false;
}

 

 

moveToState方法也會被handleLifecycleEvent方法調用,這個方法作用是改變生命週期狀態,同時通知觀察者,如果現在的生命週期狀態和最近一次調用這個方法的生命週期狀態一樣的話,調用這個方法是沒有影響的,代碼如下:

// LifecycleRegistry.java
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    State next = getStateAfter(event);
    moveToState(next);
}

 

那LifecycleRegistry對象是什麼時候創建呢?有什麼作用呢?我們的示例代碼中MainActivity是繼承AppCompatActivity的,AppCompatActivity繼承FragmentActivity,FragmentActivity繼承androidx.activity.ComponentActivity,我們看下androidx.activity.ComponentActivity的代碼:

// androidx.activity.ComponentActivity.java
// 創建LifecycleRegistry對象
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mSavedStateRegistryController.performRestore(savedInstanceState);
    // 注入ReportFragment
    ReportFragment.injectIfNeededIn(this);
    if (mContentLayoutId != 0) {
        setContentView(mContentLayoutId);
    }
}

 

我們看下ReportFragment部分代碼,代碼如下:

// ReportFragment.java
private static final String REPORT_FRAGMENT_TAG = "androidx.lifecycle"
        + ".LifecycleDispatcher.report_fragment_tag";

public static void injectIfNeededIn(Activity activity) {
    // ProcessLifecycleOwner應該總是要正確工作,有一些Activity可能不繼承support lib的FragmentActivity,所以使用framework的Fragment
    android.app.FragmentManager manager = activity.getFragmentManager();
    if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
        manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
        // Hopefully, we are the first to make a transaction.
        manager.executePendingTransactions();
    }
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    dispatchCreate(mProcessListener);
    // 調用了dispatch方法,傳入Lifecycle.Event.ON_CREATE
    dispatch(Lifecycle.Event.ON_CREATE);
}

@Override
public void onStart() {
    super.onStart();
    dispatchStart(mProcessListener);
    // 調用dispatch方法,傳入Lifecycle.Event.ON_START
    dispatch(Lifecycle.Event.ON_START);
}

@Override
public void onResume() {
    super.onResume();
    dispatchResume(mProcessListener);
    // 調用dispatch方法,傳入Lifecycle.Event.ON_RESUME
    dispatch(Lifecycle.Event.ON_RESUME);
}

@Override
public void onPause() {
    super.onPause();
    // 調用dispatch方法,傳入Lifecycle.Event.ON_PAUSE
    dispatch(Lifecycle.Event.ON_PAUSE);
}

@Override
public void onStop() {
    super.onStop();
    // 調用dispatch方法,傳入Lifecycle.Event.ON_STOP
    dispatch(Lifecycle.Event.ON_STOP);
}

@Override
public void onDestroy() {
    super.onDestroy();
    // 調用dispatch方法,傳入Lifecycle.Event.ON_DESTROY
    dispatch(Lifecycle.Event.ON_DESTROY);
    // 保證不泄露某個Activity的引用
    mProcessListener = null;
}

private void dispatch(Lifecycle.Event event) {
    Activity activity = getActivity();
    // 判斷Activity是否實現LifecycleRegistryOwner接口
    if (activity instanceof LifecycleRegistryOwner) {
        // 調用handleLifecycleEvent方法
        ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
        return;
    }

    // 判斷Activity是否實現LifecycleOwner接口
    if (activity instanceof LifecycleOwner) {
        Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
        // 判斷Lifecycle是否是LifecycleRegistry的子類
        if (lifecycle instanceof LifecycleRegistry) {
            // 調用handleLifecycleEvent方法
            ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
        }
    }
}

ReportFragment的作用是爲了感知Activity的生命週期,每當Activity的生命週期發生變化的時候,就會調用LifecycleRegistry的handleLifecycleEvent方法,然後就會調用moveToState方法,最後就會調用sync方法,從而讓LiveData能感知Activity的生命週期,其實這也是Android Jetpack的另外一個很重要的組件Lifecycle的原理,同樣我們也看下Fragment的代碼:

// Fragment.java
LifecycleRegistry mLifecycleRegistry;

@Nullable FragmentViewLifecycleOwner mViewLifecycleOwner;
MutableLiveData<LifecycleOwner> mViewLifecycleOwnerLiveData = new MutableLiveData<>();

private void initLifecycle() {
    // 創建LifecycleRegistry對象
    mLifecycleRegistry = new LifecycleRegistry(this);
    mSavedStateRegistryController = SavedStateRegistryController.create(this);
    // 判斷當前Android版本是否大於4.4
    if (Build.VERSION.SDK_INT >= 19) {
        mLifecycleRegistry.addObserver(new LifecycleEventObserver() {
            @Override
            public void onStateChanged(@NonNull LifecycleOwner source,
                    @NonNull Lifecycle.Event event) {
                // 判斷當前事件是否是ON_STOP
                if (event == Lifecycle.Event.ON_STOP) {
                    // 判斷View是否爲null
                    if (mView != null) {
                        // 如果不是空的話,取消之前發佈到事件隊列的任何延遲的高級別輸入事件
                        mView.cancelPendingInputEvents();
                    }
                }
            }
        });
    }
}

void performCreate(Bundle savedInstanceState) {
    // 省略部分代碼
    // 調用handleLifecycleEvent,傳入Lifecycle.Event.ON_CREATE
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}

void performCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
    mChildFragmentManager.noteStateNotSaved();
    mPerformedCreateView = true;
    // 創建Fragment的View的LifecycleOwner
    mViewLifecycleOwner = new FragmentViewLifecycleOwner();
    mView = onCreateView(inflater, container, savedInstanceState);
    // 判斷View是否爲null
    if (mView != null) {
        // 創建Fragment的View的Lifecycle
        mViewLifecycleOwner.initialize();
        // 然後通知新的LifecycleOwner的一些觀察者
        mViewLifecycleOwnerLiveData.setValue(mViewLifecycleOwner);
    } else {
        // 判斷FragmentViewLifecycleOwner是否初始化
        if (mViewLifecycleOwner.isInitialized()) {
            // 如果View是null,同時FragmentViewLifecycleOwner也初始化了,拋出異常
            throw new IllegalStateException("Called getViewLifecycleOwner() but "
                    + "onCreateView() returned null");
        }
        mViewLifecycleOwner = null;
    }
}

void performStart() {
    // 省略部分代碼
    // 調用onStart方法
    onStart();
    // 省略部分代碼
    // 調用LifecycleRegistry的handleLifecycleEvent方法,傳入Lifecycle.Event.ON_START
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    // 判斷View是否爲null
    if (mView != null) {
        // 如果View不是null,調用FragmentViewLifecycleOwner的handleLifecycleEvent,傳入Lifecycle.Event.ON_START
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
    }
    // 省略部分代碼
}

void performResume() {
    // 省略部分代碼
    // 調用onResume方法
    onResume();
    // 省略部分代碼
    // 調用LifecycleRegistry的handleLifecycleEvent方法,傳入Lifecycle.Event.ON_RESUME
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    // 判斷View是否爲null
    if (mView != null) {
        // 如果View不是null,調用FragmentViewLifecycleOwner的handleLifecycleEvent,傳入Lifecycle.Event.ON_RESUME
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    }
    // 省略部分代碼
}

void performPause() {
    // 省略部分代碼
    // 判斷View是否爲null
    if (mView != null) {
        // 如果View不是null,調用FragmentViewLifecycleOwner的handleLifecycleEvent方法,傳入Lifecycle.Event.ON_PAUSE
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
    }
    // 調用LifecycleRegistry的handleLifecycleEvent方法,傳入Lifecycle.Event.ON_PAUSE
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
    // 省略部分代碼
    // 調用onPause方法
    onPause();
    // 省略部分代碼
}

void performStop() {
    // 省略部分代碼
    // 判斷View是否爲null
    if (mView != null) {
        // 如果View不是null,調用FragmentViewLifecycleOwner的handleLifecycleEvent方法,傳入Lifecycle.Event.ON_STOP
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
    }
    // 調用LifecycleRegistry的handleLifecycleEvent方法,傳入Lifecycle.Event.ON_STOP
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
    // 省略部分代碼
    // 調用onStop方法
    onStop();
    // 省略部分代碼
}

void performDestroyView() {
    // 判斷View是否爲null
    if (mView != null) {
        // 如果View不是null,調用FragmentViewLifecycleOwner的handleLifecycleEvent方法,傳入Lifecycle.Event.ON_DESTROY
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
    }
    // 省略部分代碼
    onDestroyView();
    // 省略部分代碼
}

void performDestroy() {
    // 省略部分代碼
    // 調用LifecycleRegistry的handleLifecycleEvent方法,傳入Lifecycle.Event.ON_DESTROY
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
    // 省略部分代碼
    // 調用onDestroy方法
    onDestroy();
    // 省略部分代碼
}

FragmentViewLifecycleOwner表示的是Fragment的View的生命週期,在大多數情況下,這反映了Fragment本身的生命週期,但是Fragment的生命週期肯定會比它的View的生命週期要長。

 

同理,每當Fragment的生命週期發生變化的時候,就會調用LifecycleRegistry的handleLifecycleEvent方法和FragmentViewLifecycleOwner的handleLifecycleEvent方法,然後就會調用moveToState方法,最後就會調用sync方法,從而讓LiveData能感知Fragment的生命週期。

 

然後我們再看下removeObserver方法,代碼如下:

// LiveData.java
// 這個方法要在主線程調用
@MainThread
public void removeObserver(@NonNull final Observer<? super T> observer) {
    // 判斷是否在主線程
    assertMainThread("removeObserver");
    ObserverWrapper removed = mObservers.remove(observer);
    if (removed == null) {
        // 如果是null的話就return
        return;
    }
    // 調用LifecycleBoundObserver的detachObserver方法
    removed.detachObserver();
    // 調用LifecycleBoundObserver的activeStateChanged方法,並且傳入false,這個方法在上面也分析過了,這裏不再贅述
    removed.activeStateChanged(false);
}

 

 

detachObserver方法的代碼如下:

// LiveData.java
@Override
void detachObserver() {
    // 調用LifecycleRegistry的removeObserver方法
    mOwner.getLifecycle().removeObserver(this);
}

 

removeObserver方法的代碼如下:

// LifecycleRegistry.java
@Override
public void removeObserver(@NonNull LifecycleObserver observer) {
    // 移除這個觀察者
    mObserverMap.remove(observer);
}

 

根據上面的代碼可知,系統也會幫我們調用這個方法來移除觀察者,防止發生內存泄露。

 

以上就是LiveData能感知生命週期的原理。還有一個方法也比較常用:observeForever方法,我們看下它的代碼:

// LiveData.java
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
    assertMainThread("observeForever");
    // 創建AlwaysActiveObserver
    AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    if (existing instanceof LiveData.LifecycleBoundObserver) {
        // 如果existing是LiveData.LifecycleBoundObserver類的實例,拋出異常
        throw new IllegalArgumentException("Cannot add the same observer"
                + " with different lifecycles");
    }
    if (existing != null) {
        return;
    }
    // 調用AlwaysActiveObserver的activeStateChanged方法,並且傳入true
    wrapper.activeStateChanged(true);
}

 

再看下AlwaysActiveObserver的代碼:

// LiveData.java
private class AlwaysActiveObserver extends ObserverWrapper {

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

    // 重寫了shouldBeActive方法,並且返回true,根據上面的代碼分析可知,這個方法是用來判斷是否爲活躍狀態,這裏一直返回true,也就是說一直保持着活躍狀態
    @Override
    boolean shouldBeActive() {
        return true;
    }
}

observeForever是用於將指定的觀察者添加到觀察列表中,類似於調用observer方法,但是給定的LifecycleOwner狀態總是爲活躍狀態,這意味着觀察者將永遠接收所有的事件,所以如果要停止觀察這個LiveData,就要手動調用removeObserver方法。

 

然後我們再看下另外三個重要的方法的源碼:setValue方法、postValue方法和getValue方法,setValue方法和postValue方法是用於給LiveData設值,getValue方法是用於從LiveData取值,代碼如下:

// LiveData.java
final Object mDataLock = new Object();

protected void postValue(T value) {
    boolean postTask;
    // 同步鎖作用於mDataLock對象
    synchronized (mDataLock) {
        // postTask用mPendingData的值是否爲NOT_SET來判斷是否需要將Runnable添加到消息隊列
        postTask = mPendingData == NOT_SET;
        // 將value賦值給mPendingData
        mPendingData = value;
    }
    // 判斷是否需要將Runnable添加到消息隊列
    if (!postTask) {
        // 如果不需要將Runnable添加到消息隊列就return
        return;
    }
    // 如果需要將Runnable添加到消息隊列就調用ArchTaskExecutor的postToMainThread方法,下面會對這個方法分析
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

// setValue必須在主線程調用
@MainThread
protected void setValue(T value) {
    // 檢查是否在主線程
    assertMainThread("setValue");
    // mVersion自增
    mVersion++;
    // 將value賦值給mData
    mData = value;
    // 調用dispatchingValue方法
    dispatchingValue(null);
}

@SuppressWarnings("unchecked")
// 值爲可空的對象
@Nullable
public T getValue() {
    Object data = mData;
    // 判斷mData的值是否爲NOT_SET
    if (data != NOT_SET) {
        // 如果mData的值不是NOT_SET就返回這個值
        return (T) data;
    }
    // 如果mData的值爲NOT_SET就返回null
    return null;
}

我們看下postToMainThread方法,代碼如下:

// ArchTaskExecutor.java
@NonNull
private TaskExecutor mDelegate;

private ArchTaskExecutor() {
    // 創建DefaultTaskExecutor對象
    mDefaultTaskExecutor = new DefaultTaskExecutor();
    // 將mDefaultTaskExecutor賦值給mDelegate
    mDelegate = mDefaultTaskExecutor;
}

// 獲取ArchTaskExecutor單一實例的方法,使用雙重檢查鎖定(Double Check Locking,簡稱DCL)實現單例
@NonNull
public static ArchTaskExecutor getInstance() {
    if (sInstance != null) {
        return sInstance;
    }
    synchronized (ArchTaskExecutor.class) {
        if (sInstance == null) {
            // 調用ArchTaskExecutor的構造方法
            sInstance = new ArchTaskExecutor();
        }
    }
    return sInstance;
}

@Override
public void postToMainThread(Runnable runnable) {
    // 調用DefaultTaskExecutor的postToMainThread方法
    mDelegate.postToMainThread(runnable);
}

ArchTaskExecutor繼承TaskExecutor,用於執行一些公共任務,我們看到postToMainThread方法是會調用DefaultTaskExecutor的postToMainThread方法,代碼如下:

// DefaultTaskExecutor.java
@Override
public void postToMainThread(Runnable runnable) {
    if (mMainHandler == null) {
        synchronized (mLock) {
            if (mMainHandler == null) {
                // 創建Handler,傳入的是主線程的Looper
                mMainHandler = createAsync(Looper.getMainLooper());
            }
        }
    }
    // 將runnable添加到消息隊列,runnable將在主線程中執行
    mMainHandler.post(runnable);
}

 

然後我們看下傳入的Runnable:mPostValueRunnable,代碼如下:

// LiveData.java
final Object mDataLock = new Object();

private final Runnable mPostValueRunnable = new Runnable() {
    @SuppressWarnings("unchecked")
    @Override
    public void run() {
        Object newValue;
        // 同步鎖作用於mDataLock對象
        synchronized (mDataLock) {
            // 將mPendingData賦值給newValue
            newValue = mPendingData;
            // 將mPendingData設值爲NOT_SET
            mPendingData = NOT_SET;
        }
        // 調用setValue方法,傳入newValue
        setValue((T) newValue);
    }
};

 

postValue方法最後是會調用setValue方法,如果在主線程執行已發佈的任務之前多次調用這個方法,只會分發最後一個值,還有一點需要注意的是,假設先調用postValue方法,並且傳入a,然後調用setValue方法,並且傳入b,那麼會先設置爲b,然後再設置爲a。

 

postValue方法最後還是會調用setValue方法,然後就會調用dispatchingValue方法,並且傳入null,這個方法在上面也分析過了,這裏大概說一下,如果傳入的是null的話,就會遍歷所有的觀察者,然後分發內容,調用Observer的onChanged方法,執行我們的邏輯。

 

/   題外話   /

 

在示例代碼中,我用到了Android Jetpack的另外一個組件:DataBinding,同時調用了ViewDataBinding的setLifecycleOwner方法,代碼如下:

// FirstFragment.kt
binding.lifecycleOwner = this

 

我們看下對應的源碼:

// ViewDataBinding.java
@MainThread
public void setLifecycleOwner(@Nullable LifecycleOwner lifecycleOwner) {
    // 省略部分代碼
    mLifecycleOwner = lifecycleOwner;
    if (lifecycleOwner != null) {
        if (mOnStartListener == null) {
            mOnStartListener = new OnStartListener(this);
        }
        // 調用addObserver方法
        lifecycleOwner.getLifecycle().addObserver(mOnStartListener);
    }
    for (WeakListener<?> weakListener : mLocalFieldObservers) {
        if (weakListener != null) {
            // 調用WeakListener的setLifecycleOwner方法
            weakListener.setLifecycleOwner(lifecycleOwner);
        }
    }
}

setLifecycleOwner方法的代碼如下:

// ViewDataBinding.java
public void setLifecycleOwner(LifecycleOwner lifecycleOwner) {
    mObservable.setLifecycleOwner(lifecycleOwner);
}

 

這裏的mObservable爲LiveDataListener,LiveDataListener也實現了Observer接口,所以我們看下相關的代碼,代碼如下:

// ViewDataBinding.java
@Override
public void setLifecycleOwner(LifecycleOwner lifecycleOwner) {
    LifecycleOwner owner = (LifecycleOwner) lifecycleOwner;
    LiveData<?> liveData = mListener.getTarget();
    if (liveData != null) {
        if (mLifecycleOwner != null) {
            liveData.removeObserver(this);
        }
        if (lifecycleOwner != null) {
            // 調用LiveData的observe方法
            liveData.observe(owner, this);
        }
    }
    mLifecycleOwner = owner;
}

// 根據上面分析可知,當數據發生改變的時候就會調用onChanged方法
@Override
public void onChanged(@Nullable Object o) {
    ViewDataBinding binder = mListener.getBinder();
    if (binder != null) {
        // 通知對應的UI更新
        binder.handleFieldChange(mListener.mLocalFieldId, mListener.getTarget(), 0);
    }
}

 

setLifecycleOwner方法是用於設置LifecycleOwner,用於觀察綁定中的LiveData的更改,如果LiveData位於其中一個Binding表達式中,但是沒有設置LifecycleOwner,那麼LiveData將不會被觀察到,對它的更新也不會使UI發生更新。

 

另外我也用到了Kotlin協程,代碼如下:

// MainViewModel.kt
fun changeSecondContent(text: String) =
    viewModelScope.launch {
        withContext(Dispatchers.Default) {
            _secondContent.postValue(text)
        }
    }

 

viewModelScope是將協程範圍綁定到ViewModel,也就是說如果ViewModel被清除的話,這個協程範圍也會被取消,在示例代碼中,MainViewModel生命週期和MainActivity的生命週期保持一致,防止在Activity銷燬後協程還在執行更新UI的邏輯,還持有着UI控件的引用,導致內存泄露。

 

調用了withContext方法,並且傳入了Dispatchers.Default,也就是說使用Dispatchers.Default調度器調用指定的掛起塊,掛起直到完成,並且返回結果,其中Dispatchers.Default使用了共享的後臺線程池,也就是說調用postValue方法這段邏輯是在工作線程執行的,從而演示在工作線程去設置LiveData的值,並且更新對應的UI控件。

 

我的GitHub:TanJiaJunBeyond地址如下所示:

https://github.com/TanJiaJunBeyond

 

Android通用框架:Android通用框架(Kotlin-MVVM)地址如下:

https://github.com/TanJiaJunBeyond/AndroidGenericFramework

 

推薦閱讀:

讓你的Android應用快速定位耗時方法

聊聊Java的GC機制

apply()和commit()的區別你知道嗎?

發佈了177 篇原創文章 · 獲贊 55 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章