Android进阶宝典 -- Jetpack篇(最新LiveData LifeCycle源码分析)

Jetpack组件,如今是google力推的架构模式,它能够帮助我们快速构建项目,在JectPack丰富的组件当中,生命周期几乎是贯穿全部,万物皆始于声明周期,从本章开始,就开始深入JectPack核心组件源码

1 LiveData源码分析

看到LiveData这个名字,第一感觉这是一个数据类,其实不是的,LiveData是能够持有任意一种数据并且能够对这个数据进行观察。在LiveData之前,我们通过回调的方式获取网络请求返回的数据,从而进行View的数据展示,MVP架构就是采用这种原理,可为什么MVP越来越不受待见,是因为大量的数据接口编写,以及可能出现的回调地狱(这也是其中一个原因,不是全部)。

LiveData采用的观察者模式,能够感知数据的变化,从而通过数据驱动UI,这也是MVVM架构的核心思想,其实你也可以看做是接口的回调;除此之外,LiveData具备生命周期感知能力,只有在Activity或者Fragment处于活跃状态时,才会回调数据,能够避免内存泄漏。

1.1 MutableLiveData

public class MutableLiveData extends LiveData {

    /**
     * Creates a MutableLiveData initialized with the given {@code value}.
     *
     * @param value initial value
     */
    public MutableLiveData(T value) {
        super(value);
    }

    /**
     * Creates a MutableLiveData with no value assigned to it.
     */
    public MutableLiveData() {
        super();
    }

    @Override
    public void postValue(T value) {
        super.postValue(value);
    }

    @Override
    public void setValue(T value) {
        super.setValue(value);
    }
}

如果使用过LiveData的伙伴应该了解,在创建一个LiveData对象的时候,通常是创建了一个MutableLiveData对象,这个类是LiveData的子类,然后重写了LiveData实现的两个方法postValue和setValue。

首先LiveData是一个抽象类,不能被初始化,因此不能直接调用这两个方法,所以声明了一个子类MutableLiveData来调用父类的方法。

protected void postValue(T value) {
    boolean postTask;
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        mPendingData = value;
    }
    if (!postTask) {
        return;
    }
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

@MainThread
protected void setValue(T value) {
    assertMainThread("setValue");
    mVersion++;
    mData = value;
    dispatchingValue(null);
}

首不看具体的实现,在postValue方法中,涉及到了线程切换,postToMainThread切换到了主线程,也就是说在子线程发送数据,需要使用postValue方法

private final Runnable mPostValueRunnable = new Runnable() {
    @SuppressWarnings("unchecked")
    @Override
    public void run() {
        Object newValue;
        synchronized (mDataLock) {
            newValue = mPendingData;
            mPendingData = NOT_SET;
        }
        setValue((T) newValue);
    }
};

其实从源码中也能看到,其实postValue最终也是调用了setValue方法

1.1.1 postValue / setValue

接下来我们深入源码,看下数据是如何分发传递的,首先从postValue开始,因为postValue最终也是调用了setValue。

首先我们传入一个value值,这个值是一个泛型;因为postValue能在任意线程中调用,因此涉及到线程同步,这里加了一把锁;这里有一个标志位postTask,因为mPendingData默认值就是NOT_SET,是一个空的Object对象,所以postTask为true;

volatile Object mPendingData = NOT_SET;
static final Object NOT_SET = new Object();

紧接着,是把我们传入的值,赋值给了mPendingData,因为postTask == true,因此直接调用

ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);

切换到主线程,把mPendingData传给了newValue的同时,将mPendingData重新设置为NOT_SET,最终调用了setValue方法,其实就是将我们调用postValue传入的值,最终传给了setValue。

在setValue方法中,将传入的值赋值给了mData,mData就是LiveData中真正的数据持有者

接下来我们看到,在setValue中执行了dispatchingValue方法,传入了参数null,这个比较关键,我们看下dispatchingValue的源码

void dispatchingValue(@Nullable ObserverWrapper initiator) {
    if (mDispatchingValue) {
        mDispatchInvalidated = true;
        return;
    }
    mDispatchingValue = true;
    do {
        mDispatchInvalidated = false;
        if (initiator != null) {
            considerNotify(initiator);
            initiator = null;
        } else {
            for (Iterator, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                considerNotify(iterator.next().getValue());
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;
}

在dispatchingValue方法中,执行了一个do-while循环,因为一开始initiator传入的就是空的,那么会走到else,这里我们可以看到一个for循环遍历mObservers数组中的全部观察者,因为LiveData可以被多个观察者注册监听,因此采用了mObservers数组保存所有的观察者,当数据发生变化时,所有的观察者都能接收到数据。

当拿到其中一个观察者之后,会调用considerNotify方法,传入的就是在注册观察者的时候创建的LifecycleBoundObserver对象,后面会讲到,这里提前透露一下

private void considerNotify(ObserverWrapper observer) {
    1️⃣
    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.
    2️⃣
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);
        return;
    }
    3️⃣
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    4️⃣
    observer.mLastVersion = mVersion;
    observer.mObserver.onChanged((T) mData);
}

1️⃣ 2️⃣ 3️⃣:这个我们放在后面说,很重要的一个版本号机制

4️⃣:最终我们可以看到,considerNotify方法中调用了观察者的onChanged方法,并把mData传了进去,mData之前我们说过,其实就是我们传入的数据,也是LiveData真正的数据持有者

1.1.2 LiveData注册观察者

既然通过postValue或者setValue,最终将我们传入的数据赋值给了LiveData中的一个数据持有者mData,那么我们怎么能够观察这个数据的变化呢?LiveData提供了一个observe方法用来注册观察者。

liveData.observe(this, new Observer() {
    @Override
    public void onChanged(Object o) {

    }
});

那么我们接下来就关注一下,LiveData如何注册观察者并能够感知生命周期

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
    1️⃣
    assertMainThread("observe");
    2️⃣
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        // ignore
        return;
    }
    3️⃣
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    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;
    }
    4️⃣
    owner.getLifecycle().addObserver(wrapper);
}

在observe的源码中,我们首先看应用层传入的两个参数:

owner:对应的Activity或者Fragment,或者实现了LifecycleOwner接口的组件
observer:创建的观察者对象,其实本身就是一个接口,是一个匿名内部类

1️⃣:在注册观察者的时候,必须要保证是在主线程中注册,否则断言就会抛出异常;

2️⃣:判断当前组件的生命周期是否处于销毁状态,如果属于DESTROYED状态,那么就不会注册观察者,直接return

3️⃣:在这里是将我们传入的两个参数封装成了一个LifecycleBoundObserver对象

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

    LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer observer) {
        super(observer);
        mOwner = owner;
    }

    @Override
    boolean shouldBeActive() {
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
        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);
    }
}

其中owner是LifecycleBoundObserver持有,观察者observer则是交给了父类的构造方法,LifecycleBoundObserver的父类是ObserverWrapper

private abstract class ObserverWrapper {
    final Observer mObserver;
    boolean mActive;
    int mLastVersion = START_VERSION;

    ObserverWrapper(Observer observer) {
        mObserver = observer;
    }

    abstract boolean shouldBeActive();

    boolean isAttachedTo(LifecycleOwner owner) {
        return false;
    }

    void detachObserver() {
    }

    void activeStateChanged(boolean newActive) {
        if (newActive == mActive) {
            return;
        }
        // immediately set active state, so we'd never dispatch anything to inactive
        // owner
        mActive = newActive;
        changeActiveCounter(mActive ? 1 : -1);
        if (mActive) {
            dispatchingValue(this);
        }
    }
}

我们可以看到,ObserverWrapper是持有了observer的引用,因为LifecycleBoundObserver跟ObserverWrapper是继承关系,因此也相当于LifecycleBoundObserver持有了observer的引用。

继续看,在创建了LifecycleBoundObserver之后,是将其放入一个mObservers的map集合中,key是observer,value是LifecycleBoundObserver

private SafeIterableMap, ObserverWrapper> mObservers =
        new SafeIterableMap<>();

ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);

其中调用putIfAbsent方法,主要就是为了判断当前观察者是否已经被注册过了,如果已经存在这个key,那么返回的就不为空;

public V putIfAbsent(@NonNull K key, @NonNull V v) {
    Entry entry = get(key);
    if (entry != null) {
        return entry.mValue;
    }
    put(key, v);
    return null;
}

因此在后续判断中,会判断如果返回值不为空,那么就会抛出异常,不能重复注册

4️⃣:最终获取组件的生命周期对象,并将LifecycleBoundObserver作为观察者传进去了,这也就意味着,观察者具备了感知当前组件生命周期的能力

public abstract void addObserver(@NonNull LifecycleObserver observer);

我们可以看到,addObserver需要传入的是一个LifecycleObserver对象,这也就意味着,LifecycleBoundObserver就是这个LifecycleObserver的一个子类,我们看下上面的源码,可以看到LifecycleBoundObserver实现了LifecycleEventObserver的接口

public interface LifecycleEventObserver extends LifecycleObserver {
    /**
     * Called when a state transition event happens.
     *
     * @param source The source of the event
     * @param event The event
     */
    void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}

所以,我们可以这么理解,只要我们实现了这个接口,并且作为观察者交给组件,就能感知组件的生命周期,我们可以尝试一下。

1.1.3 自动管理生命周期

首先我们创建一个观察者对象,实现LifecycleEventObserver接口

public class MyLifeCycle implements LifecycleEventObserver {
    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {

        Log.e("TAG","event -------"+event);
        //感知组件的生命周期
        if(source.getLifecycle().getCurrentState() == Lifecycle.State.CREATED){
            Log.e("TAG","-------CREATED");
        }else if(source.getLifecycle().getCurrentState() == Lifecycle.State.RESUMED){
            Log.e("TAG","-------RESUMED");
        }
    }
}

然后作为观察者添加到组件中,这里拿MainActivity为例

this.getLifecycle().addObserver(new MyLifeCycle());

这样的话,就能感知MainActivity的生命周期,就不需要手动去onResume或者onDestory中去做相关的处理逻辑

2022-06-04 13:21:54.741 24751-24751/com.t.demo02 E/TAG: onCreate
2022-06-04 13:21:54.743 24751-24751/com.t.demo02 E/TAG: event -------ON_CREATE
2022-06-04 13:21:54.743 24751-24751/com.t.demo02 E/TAG: -------CREATED
2022-06-04 13:21:54.745 24751-24751/com.t.demo02 E/TAG: event -------ON_START
2022-06-04 13:21:54.750 24751-24751/com.t.demo02 E/TAG: event -------ON_RESUME
2022-06-04 13:21:54.750 24751-24751/com.t.demo02 E/TAG: -------RESUMED

所以LiveData之所以能够感知生命周期,就是因为LifecycleBoundObserver这个封装类实现了LifecycleEventObserver接口,并添加为组件生命周期的观察者,因此具备了感知生命周期的能力。

好的,既然LifecycleEventObserver被LifecycleBoundObserver实现,那么必然也实现了onStateChanged这个方法,我们去看一下。

@Override
public void onStateChanged(@NonNull LifecycleOwner source,
        @NonNull Lifecycle.Event event) {
    1️⃣
    Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
    if (currentState == DESTROYED) {
        removeObserver(mObserver);
        return;
    }
    2️⃣
    Lifecycle.State prevState = null;
    while (prevState != currentState) {
        prevState = currentState;
        activeStateChanged(shouldBeActive());
        currentState = mOwner.getLifecycle().getCurrentState();
    }
}

在这个方法中,就能回调组件的生命周期

1️⃣:这里拿到了组件当前的状态getCurrentState,会判断,如果当前组件已经是销毁的状态,那么就会将mObserver从mObservers中移除,mObservers就是LiveData中用来保存观察者的Map数组;所以当页面重新加载之后,会重新注册新的观察者。

这个也是LiveData能够避免内存泄漏的原因

@MainThread
public void removeObserver(@NonNull final Observer observer) {
    assertMainThread("removeObserver");
    ObserverWrapper removed = mObservers.remove(observer);
    if (removed == null) {
        return;
    }
    removed.detachObserver();
    removed.activeStateChanged(false);
}

2️⃣:因为只要每次组件的生命周期发生变化,这个方法就会被回调,因此这里是进行了状态的前后关系比较,这里while循环肯定能进去,并将prevState设置为当前组件的生命周期状态,然后调用了activeStateChanged方法,这里就是产生粘性事件的原因所在。

1.1.4 粘性事件

我们来看个一个场景

MutableLiveData liveData = new MutableLiveData();
liveData.postValue("11111");

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        liveData.observe(MainActivity.this, new Observer() {
            @Override
            public void onChanged(Object o) {
                Log.e("TAG----","result"+o);
            }
        });
    }
});

当通过LiveData发送数据之后(这里注意,我并没有注册观察者),通过点击按钮,注册观察者,这个时候发现居然收到了之前发送的消息。

按照正常的逻辑,我只有注册之后,你发送的消息我才能收到;为啥先发消息后注册也能收到呢?这就是粘性事件,使用过EventBus的伙伴应该熟悉,EventBus也存在粘性事件的场景。

首先粘性事件既然发生,那么回到第一小节的地方,我们知道在onChanged中肯定回调了数据,所以肯定是某个地方调用了dispatchingValue方法,通过源码我们可以看到除了setValue之外,在ObserverWrapper中activeStateChanged方法中调用了dispatchingValue,因为ObserverWrapper是个抽象类,因此肯定其子类能够调用。

最终定位就是在LifecycleBoundObserver的onStateChanged方法中执行了,我们知道当组件的生命周期发生变化后,这个方法会回调;

所以这里会有一个疑问❓我在点击按钮的时候,MainActivity的生命周期已经走到onResume,不会再触发onStateChanged了吧,是这样吗

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

//                liveData.observe(MainActivity.this, new Observer() {
//                    @Override
//                    public void onChanged(Object o) {
//                        Log.e("TAG----","result"+o);
//                    }
//                });
        MainActivity.this.getLifecycle().addObserver(new MyLifeCycle());
    }
});

拿我们之前在添加自定义观察者时的代码,我们也试一下,跟我们想象的好像不太一样,onStateChanged回调居然走了一遍!!

也就是说,当我点击按钮,注册一个LiveData的观察者的时候,onStateChanged也会被回调,意味着dispatchingValue可能会被执行。

这个时候,dispatchingValue传入的参数不为空,同样会调用considerNotify方法,最终在观察者的onChanged方法中回调。

还有一个问题就是,每次注册观察者,onStateChanged会被回调三次,onCreate - onStart - onResume,那么为什么在onChanged中只会被回调一次

public class MyLifeCycle implements LifecycleEventObserver {
    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {

        Lifecycle.State currentState = source.getLifecycle().getCurrentState();
        Log.e("TAG--------","currentState ---"+currentState);
        Lifecycle.State prevState = null;
        while (prevState != currentState) {

            prevState = currentState;
            Log.e("TAG--------","prevState ---"+prevState);
            currentState = source.getLifecycle().getCurrentState();
            Log.e("while TAG--------","currentState ---"+currentState);
        }
    }
}
2022-06-04 15:50:35.544 9863-9863/com.t.demo02 E/TAG--------: currentState ---CREATED
2022-06-04 15:50:35.544 9863-9863/com.t.demo02 E/TAG--------: prevState ---CREATED
2022-06-04 15:50:35.544 9863-9863/com.t.demo02 E/while TAG--------: currentState ---CREATED
2022-06-04 15:50:35.546 9863-9863/com.t.demo02 E/TAG--------: currentState ---STARTED
2022-06-04 15:50:35.546 9863-9863/com.t.demo02 E/TAG--------: prevState ---STARTED
2022-06-04 15:50:35.546 9863-9863/com.t.demo02 E/while TAG--------: currentState ---STARTED
2022-06-04 15:50:35.550 9863-9863/com.t.demo02 E/TAG--------: currentState ---RESUMED
2022-06-04 15:50:35.550 9863-9863/com.t.demo02 E/TAG--------: prevState ---RESUMED
2022-06-04 15:50:35.550 9863-9863/com.t.demo02 E/while TAG--------: currentState ---RESUMED

这里就回到了第一小节讲到的一个版本号机制

private void considerNotify(ObserverWrapper observer) {
    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;
    }

    if (observer.mLastVersion >= mVersion) {
        return;
    }
    observer.mLastVersion = mVersion;
    observer.mObserver.onChanged((T) mData);
}

这里我们看到就是当onChanged被回调一次之后,观察者的mLastVersion就被赋值为mVersion,当再次进来之后,因为mLastVersion == mVersion就直接return了。

1.1.5 版本号机制

我们看一下这个版本号,首先mLastVersion是ObserverWrapper的成员变量,默认值是-1;mVersion是LiveData的一个成员变量,如果是调用的空参构造方法,默认值也是-1,如果非空参构造方法,那么就就会将版本号+1,而且会把初始值赋值给mData,我们使用时一般都是采用空参构造方法。

public LiveData(T value) {
    mData = value;
    mVersion = START_VERSION + 1;
}

/**
 * Creates a LiveData with no value assigned to it.
 */
public LiveData() {
    mData = NOT_SET;
    mVersion = START_VERSION;
}

所以在一开始,mLastVersion和mVersion都是-1,当调用setValue的时候,mVersion++

mVersion = 0;
mLastVersion = -1;

把判断条件放在这儿

if (observer.mLastVersion >= mVersion) { return; }

这个时候 mLastVersion < mVersion,会继续往下走,这时onChanged就会被回调,观察者获取到值,此时的版本号如下。

mVersion = 0;
mLastVersion = 0;

所以我们之前讲到的,注册一个观察者会走onStateChanged三次回调,可为什么只回调了一次数据,原因就在这里了,当再次走到这个判断的时候,mLastVersion == mVersion,直接return。

通过版本号机制,就是用来防止组件生命周期变化,导致观察者重复接收多次LiveData的数据。

所以,观察者接收数据的方式有2种:
1 postValue / setValue

2 当组件的生命周期发生改变或者我们第一次注册观察者时

1.2 LiveData事件总线

像实际的开发中,我们使用LiveData不仅仅局限于当前页面的数据展示,包括跨组件、跨页面的通信,同样会使用到LiveData,那么通过LiveData来实现一个事件总线,熟悉使用EventBus的伙伴应该都清楚

/**
 * 事件总线
 */
public class LiveDataBus {

    //当前应用全部的LiveData集合
    private Map> map;
    private static LiveDataBus liveDataBus;
    private LiveDataBus(){
        map = new HashMap<>();
    }

    public static LiveDataBus getInstance(){
        if(liveDataBus == null){
            synchronized (LiveDataBus.class){
                if(liveDataBus == null){
                    liveDataBus = new LiveDataBus();
                }
            }
        }
        return liveDataBus;
    }

    public  MutableLiveData with(String key,Class clazz){
        if(!map.containsKey(key)){
            map.put(key, new MutableLiveData<>());
        }
        return (MutableLiveData) map.get(key);
    }

}

with方法用于创建新的LiveData对象或者直接返回已有的LiveData对象

MutableLiveData liveData1 = LiveDataBus.getInstance().with("key", String.class);
liveData1.postValue("1234567");

记不记得之前的小结中,提到的粘性事件,其实官方的LiveData就是存在这个粘性事件的,所以在实际的开发中,这种跳转页面传递参数没有问题,但是如果某些场景就不能使用这种粘性事件,那么官方的LiveData就不能使用了,需要我们自己去处理粘性事件。

前面提到过,粘性事件产生的主要原因就是,在注册观察者的时候,就会导致数据的回调,那么我们是不是可以在数据回调之前,就将观察者的版本号修改成与LiveData的版本号保持一致,是不就可以。

public class MyLiveData extends MutableLiveData {

    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer,Boolean isSticky) {
        super.observe(owner, observer);

        //如果不需要粘性事件
        if(isSticky){
            observe(owner,observer);
        }
    }

    @Override
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
        //hook
        try {
            hookObserver(observer);
        }catch (Exception e){

        }
    }

    private void hookObserver(Observer observer) {

        Class aClass = LiveData.class;
        //
        try {
            Field mObserversFiled = aClass.getDeclaredField("mObservers");
            mObserversFiled.setAccessible(true);
            //获取mObservers数组
            Object mObservers = mObserversFiled.get(this);
            //通过observer来获取创建的LifecycleBoundObserver
            Method getMethod = mObservers.getClass().getDeclaredMethod("get",Object.class);
            getMethod.setAccessible(true);
            //获取到LifecycleBoundObserver
            Object wrapper = null;
            Object entry = getMethod.invoke(mObservers,observer);
            if(entry != null && entry instanceof Map.Entry){
                wrapper = ((Map.Entry) entry).getValue();
            }
            if(wrapper == null){
                Log.e("TAG","没有获取到相应的LifecycleBoundObserver");
            }
            //获取到mLastVersion
            Field mLastVersionFiled = wrapper.getClass().getSuperclass().getDeclaredField("mLastVersion");
            mLastVersionFiled.setAccessible(true);
            //获取LiveData的mVersion
            Field mVersionFiled = aClass.getDeclaredField("mVersion");
            mVersionFiled.setAccessible(true);
            Object mVersion = mVersionFiled.get(this);

            //赋值
            mLastVersionFiled.set(wrapper,mVersion);
        }catch (Exception e){

            Log.e("TAG","ecp --- "+e);
        }
    }
}

这里是重写了LiveData,并且传入了一个参数isSticky来确认是否需要粘性事件,如果需要粘性事件,那么就直接走正常的LiveData的注册逻辑;

如果不需要粘性事件,那么其实就是通过hook的方式来修改观察者observer的版本号mLastVersion等于LiveData的版本号mVersion,基本的反射操作,其实通过前面的源码讲解,这块就非常简单了。

大家其实没必要担心hook之后影响当前组件的数据发送,因为每次post或者set都会增加mVersion的版本号,肯定是能够回调onChanged方法!

2 LifeCycle源码分析

其实在LiveData的源码中,我们已经接触到了LifeCycle,其实LifeCycle的出现,真的是极大地解放了我们的双手,能够动态感知组件的生命周期,那么LifeCycle是怎么做到的呢?

2.1 getLifecycle

owner.getLifecycle().addObserver(wrapper);

我们拿LiveData中observe方法的最后一行代码入手,首先调用了getLifecycle方法

public interface LifecycleOwner {
    /**
     * Returns the Lifecycle of the provider.
     *
     * @return The lifecycle of the provider.
     */
    @NonNull
    Lifecycle getLifecycle();
}

LifeCycle是一个抽象类,获取到的肯定是它的一个子类,我们先从Activity组件入手,看看getLifecycle拿到的是什么。

public Lifecycle getLifecycle() {
    // Instead of directly using the Activity's Lifecycle, we
    // use a LifecycleRegistry that is nested exactly outside of
    // when Fragments get their lifecycle changed
    // TODO(b/127528777) Drive Fragment Lifecycle with LifecycleObserver
    return mFragmentLifecycleRegistry;
}

通过FragmentActivity源码中的getLifecycle方法我们得知,getLifecycle拿到的是一个LifecycleRegistry对象,它就是LifeCycle的一个子类。

其实调用addObserver,就是调用了LifecycleRegistry的addObserver方法

2.2 addObserver

@Override
public void addObserver(@NonNull LifecycleObserver observer) {
    enforceMainThreadIfNeeded("addObserver");
    1️⃣
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    2️⃣
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
    3️⃣
    if (previous != null) {
        return;
    }
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    if (lifecycleOwner == null) {
        // it is null we should be destroyed. Fallback quickly
        return;
    }

    boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
    State targetState = calculateTargetState(observer);
    mAddingObserverCounter++;
    while ((statefulObserver.mState.compareTo(targetState) < 0
            && mObserverMap.contains(observer))) {
        pushParentState(statefulObserver.mState);
        final Event event = Event.upFrom(statefulObserver.mState);
        if (event == null) {
            throw new IllegalStateException("no event up from " + statefulObserver.mState);
        }
        statefulObserver.dispatchEvent(lifecycleOwner, event);
        popParentState();
        // mState / subling may have been changed recalculate
        targetState = calculateTargetState(observer);
    }

    if (!isReentrance) {
        4️⃣
        // we do sync only on the top level.
        sync();
    }
    mAddingObserverCounter--;
}

我们接下来着重看下,addObserver源码,看我们的观察者究竟是如何感知到声明周期的

1️⃣:首先会设置一个初始化状态initialState,其值取决于mState的状态,mState就是当前组件的状态,如果不是销毁状态,那么就是初始化状态,最终会赋值给initialState

2️⃣:这个地方是不很熟悉了,它又去创建了一个ObserverWithState对象,将观察者和观察者所处组件的状态传入,生成一个带状态的观察者,放进一个mObserverMap,跟LiveData注册如出一辙。

private FastSafeIterableMap mObserverMap =
        new FastSafeIterableMap<>();

3️⃣:如果已经注册过了,就直接return

4️⃣:核心代码

private void sync() {
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    if (lifecycleOwner == null) {
        throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
                + "garbage collected. It is too late to change lifecycle state.");
    }
    1️⃣
    while (!isSynced()) {
        mNewEventOccurred = false;
        // no need to check eldest for nullability, because isSynced does it for us.
        2️⃣
        if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
            backwardPass(lifecycleOwner);
        }
        Map.Entry newest = mObserverMap.newest();
        3️⃣
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > 0) {
            forwardPass(lifecycleOwner);
        }
    }
    mNewEventOccurred = false;
}

在sync方法中,就涉及到了生命周期的同步和对齐

1️⃣:进入while循环

2️⃣:mState代表当前组件的生命周期,要么是DESTROYED,要么是INITIALIZED,现在在前台肯定就是INITIALIZED

public enum State {
    /**
    0
     */
    DESTROYED,

    /**
     1
     */
    INITIALIZED,

    /**
    2
     */
    CREATED,

    /**
    3
     */
    STARTED,

    /**
    4
     */
    RESUMED;

    /**
     * Compares if this State is greater or equal to the given {@code state}.
     *
     * @param state State to compare with
     * @return true if this State is greater or equal to the given {@code state}
     */
    public boolean isAtLeast(@NonNull State state) {
        return compareTo(state) >= 0;
    }
}

然后会跟mObserverMap中观察者做对比,因为一开始在创建ObserverWithState对象的时候,传入的State就是INITIALIZED,所以 mObserverMap.eldest().getValue().mState == INITIALIZED

static class ObserverWithState {
    State mState;
    LifecycleEventObserver mLifecycleObserver;

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

    void dispatchEvent(LifecycleOwner owner, Event event) {
        State newState = event.getTargetState();
        mState = min(mState, newState);
        //看到了吗
        mLifecycleObserver.onStateChanged(owner, event);
        mState = newState;
    }
}

这个时候,组件的生命周期发生变化,mState从INITIALIZED变为CREATED,这个时候mState比INITIALIZED大,就进入3️⃣

private void forwardPass(LifecycleOwner lifecycleOwner) {
    Iterator> ascendingIterator =
            mObserverMap.iteratorWithAdditions();
    while (ascendingIterator.hasNext() && !mNewEventOccurred) {
        Map.Entry entry = ascendingIterator.next();
        ObserverWithState observer = entry.getValue();
        while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            pushParentState(observer.mState);
            final Event event = Event.upFrom(observer.mState);
            if (event == null) {
                throw new IllegalStateException("no event up from " + observer.mState);
            }
            observer.dispatchEvent(lifecycleOwner, event);
            popParentState();
        }
    }
}

3️⃣:forwardPass,其实就是将mObserverMap所有观察者的生命周期同步到与组件一致,调用了观察者的dispatchEvent

在dispatchEvent方法中,我们看到了LifecycleEventObserver的onStateChanged方法被调用,所以我们应该知道为什么onStateChanged会被调用多次了?就是因为LifeCycle生命周期的同步导致的

Android进阶宝典 -- Jetpack篇(最新LiveData LifeCycle源码分析)_第1张图片

看上面这张图,应该也就明白了。

当然,我们这里也只是看到了生命周期的同步跟回调,我在添加观察者的时候,我只是做了状态的初始化,那么后续的触发点在哪呢?

看到下面这张图就能明白了!

Android进阶宝典 -- Jetpack篇(最新LiveData LifeCycle源码分析)_第2张图片

在FragmentActivity中,LifeCycleRegistry在每个生命周期回调的时候,都调用了handleLifecycleEvent,在handleLifecycleEvent方法中,其实就拿到了当前组件的生命周期,然后给mState赋值,同时调用了sync同步方法进行生命周期对齐

public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    enforceMainThreadIfNeeded("handleLifecycleEvent");
    moveToState(event.getTargetState());
}

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;
    }
    mHandlingEvent = true;
    sync();
    mHandlingEvent = false;
}

像现在所有的Activity都是继承自AppcompatActivity,如果像之前的继承自Activity,如果想要观察者能够感知当前组件的生命周期,就需要实现LifecycleOwner,自己创建一个LifecycleRegistry对象

public class MainActivity extends Activity implements LifecycleOwner {
    private LifecycleRegistry mRegistry = new LifecycleRegistry(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);

        MainActivity.this.getLifecycle().addObserver(new MyLifeCycle());
    }

    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return mRegistry;
    }

    @Override
    protected void onResume() {
        super.onResume();
        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    }

    @Override
    protected void onStart() {
        super.onStart();
        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    }
}

这样在添加观察者的时候,获取到的Lifecycle对象就是mRegistry,而且在不同的生命周期中,mRegistry都调用了handleLifecycleEvent方法,因此MyLifeCycle同样能够感知Activity的生命周期变化。

作者:想要成为专家的Lay
链接:https://juejin.cn/post/7105367601517166623
更多Android资料可点击下方卡片~

你可能感兴趣的:(Android,Jetpack,android,ui,android,studio)