理解响应式编程,来一波LiveData的深入解析吧!

/   今日科技快讯   /

近日,特斯拉国产Model 3正式交付,其国产化进入正轨。这也意味着它与国内造车新势力的交锋从媒体上走向现实。更早之前的1月3日,特斯拉宣布对国产版Model 3降价,售价从35.58万元/辆降至32.38万元/辆,加上免征购置税和新能源汽车的补贴,Model 3低配版售价更是跌破30万元大关。

/   作者简介   /

本篇文章来自谭嘉俊的投稿,分享了他对Android Jetpack系列——LiveData源码分析的理解,相信会对大家有所帮助!同时也感谢作者贡献的精彩文章。

谭嘉俊的博客地址:

https://www.jianshu.com/u/257511d0c878

/   开始   /

本文章主要是对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 FirstFragment : Fragment(), FirstHandlers {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? =
        DataBindingUtil.inflate<FragmentFirstBinding>(
            inflater,
            R.layout.fragment_first,
            container,
            false
        )
            .also { binding ->
                // 调用了setLifecycleOwner方法,下面会分析   
                binding.lifecycleOwner = this
                // 使MainViewModel与视图绑定   
                binding.viewModel = activity?.let {
                    ViewModelProviders.of(it)[MainViewModel::class.java]
                }
                binding.handlers = this
            }
            .root

    // 点击Button导航到SecondFragment
    override fun onNavigateToSecondFragmentClick(view: View) {
        (activity as MainActivity).addFragment(SecondFragment(), FRAGMENT_TAG_SECOND)
    }

}

interface FirstHandlers {

    fun onNavigateToSecondFragmentClick(view: View)

}

定义SecondFragment,代码如下:

/**
 * 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()的区别你知道吗?

欢迎关注我的公众号

学习技术或投稿

长按上图,识别图中二维码即可关注

发布了362 篇原创文章 · 获赞 237 · 访问量 41万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览