Android Advanced Collection -- Jetpack (the latest LiveData LifeCycle source code analysis)

The Jetpack component is now an architectural pattern pushed by google. It can help us build projects quickly. Among the rich components of JectPack, the life cycle runs through almost all of them. Everything starts from the declaration cycle. From this chapter, we begin to penetrate the core of JectPack. Component source code

1 LiveData source code analysis

Seeing the name LiveData, the first impression is that this is a data class, but it is not. LiveData can hold any kind of data and can observe this data. Before LiveData, we obtained the data returned by the network request through the callback method, so as to display the data of the View. The MVP architecture adopts this principle, but why MVP is becoming more and more unpopular, because a large number of data interfaces are written. And possible callback hell (that's one reason, not all).

The observer mode adopted by LiveData can perceive the changes of data and drive the UI through data, which is also the core idea of ​​MVVM architecture. In fact, you can also regard it as the callback of the interface; Only when the Activity or Fragment is active, the data will be called back, which can avoid memory leaks.

1.1 MutableLiveData

public class MutableLiveData<T> extends LiveData<T> {

    /**
     * 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);
    }
}
复制代码

If you have used LiveData, you should know that when you create a LiveData object, you usually create a MutableLiveData object, which is a subclass of LiveData, and then override the two methods postValue and setValue implemented by LiveData.

First of all, LiveData is an abstract class that cannot be initialized, so these two methods cannot be called directly, so a subclass MutableLiveData is declared to call the methods of the parent class.

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);
}
复制代码

First of all, regardless of the specific implementation, in the postValue method, thread switching is involved, and postToMainThread switches to the main thread, that is to say, the postValue method needs to be used to send data in the child thread

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

In fact, it can be seen from the source code that postValue finally calls the setValue method.

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<Map.Entry<Observer<? super T>, 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<? super T> 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<? super T> 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<? super T> mObserver;
    boolean mActive;
    int mLastVersion = START_VERSION;

    ObserverWrapper(Observer<? super T> 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<Observer<? super T>, ObserverWrapper> mObservers =
        new SafeIterableMap<>();

ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
复制代码

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

public V putIfAbsent(@NonNull K key, @NonNull V v) {
    Entry<K, V> 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<? super T> 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<String, MutableLiveData<Object>> 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 <T> MutableLiveData<T> with(String key,Class<T> clazz){
        if(!map.containsKey(key)){
            map.put(key, new MutableLiveData<>());
        }
        return (MutableLiveData<T>) map.get(key);
    }
    
}
复制代码

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

MutableLiveData<String> liveData1 = LiveDataBus.getInstance().with("key", String.class);
liveData1.postValue("1234567");
复制代码

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

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

public class MyLiveData<T> extends MutableLiveData<T> {


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

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

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

        }
    }

    private void hookObserver(Observer<? super T> observer) {

        Class<LiveData> 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<LifecycleObserver, ObserverWithState> 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<LifecycleObserver, ObserverWithState> 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<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
            mObserverMap.iteratorWithAdditions();
    while (ascendingIterator.hasNext() && !mNewEventOccurred) {
        Map.Entry<LifecycleObserver, ObserverWithState> 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生命周期的同步导致的

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

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

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

image.png

在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的生命周期变化。

Guess you like

Origin juejin.im/post/7105367601517166623