Jetpack组件,如今是google力推的架构模式,它能够帮助我们快速构建项目,在JectPack丰富的组件当中,生命周期几乎是贯穿全部,万物皆始于声明周期,从本章开始,就开始深入JectPack核心组件源码
1 LiveData源码分析
看到LiveData这个名字,第一感觉这是一个数据类,其实不是的,LiveData是能够持有任意一种数据并且能够对这个数据进行观察。在LiveData之前,我们通过回调的方式获取网络请求返回的数据,从而进行View的数据展示,MVP架构就是采用这种原理,可为什么MVP越来越不受待见,是因为大量的数据接口编写,以及可能出现的回调地狱(这也是其中一个原因,不是全部)。
LiveData采用的观察者模式,能够感知数据的变化,从而通过数据驱动UI,这也是MVVM架构的核心思想,其实你也可以看做是接口的回调;除此之外,LiveData具备生命周期感知能力,只有在Activity或者Fragment处于活跃状态时,才会回调数据,能够避免内存泄漏。
1.1 MutableLiveData
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29public 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); } }
如果使用过LiveData的伙伴应该了解,在创建一个LiveData对象的时候,通常是创建了一个MutableLiveData对象,这个类是LiveData的子类,然后重写了LiveData实现的两个方法postValue和setValue。
首先LiveData是一个抽象类,不能被初始化,因此不能直接调用这两个方法,所以声明了一个子类MutableLiveData来调用父类的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20protected 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方法
1
2
3
4
5
6
7
8
9
10
11
12
13private 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;
1
2
3volatile Object mPendingData = NOT_SET; static final Object NOT_SET = new Object();
紧接着,是把我们传入的值,赋值给了mPendingData,因为postTask == true,因此直接调用
1
2ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
切换到主线程,把mPendingData传给了newValue的同时,将mPendingData重新设置为NOT_SET,最终调用了setValue方法,其实就是将我们调用postValue传入的值,最终传给了setValue。
在setValue方法中,将传入的值赋值给了mData,mData就是LiveData中真正的数据持有者
接下来我们看到,在setValue中执行了dispatchingValue方法,传入了参数null,这个比较关键,我们看下dispatchingValue的源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24void 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对象,后面会讲到,这里提前透露一下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24private 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方法用来注册观察者。
1
2
3
4
5
6
7liveData.observe(this, new Observer() { @Override public void onChanged(Object o) { } });
那么我们接下来就关注一下,LiveData如何注册观察者并能够感知生命周期
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23@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对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41class 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32private 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
1
2
3
4
5private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers = new SafeIterableMap<>(); ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
其中调用putIfAbsent方法,主要就是为了判断当前观察者是否已经被注册过了,如果已经存在这个key,那么返回的就不为空;
1
2
3
4
5
6
7
8
9public 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作为观察者传进去了,这也就意味着,观察者具备了感知当前组件生命周期的能力
1
2public abstract void addObserver(@NonNull LifecycleObserver observer);
我们可以看到,addObserver需要传入的是一个LifecycleObserver对象,这也就意味着,LifecycleBoundObserver就是这个LifecycleObserver的一个子类,我们看下上面的源码,可以看到LifecycleBoundObserver实现了LifecycleEventObserver的接口
1
2
3
4
5
6
7
8
9
10public 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接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14public 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为例
1
2this.getLifecycle().addObserver(new MyLifeCycle());
这样的话,就能感知MainActivity的生命周期,就不需要手动去onResume或者onDestory中去做相关的处理逻辑
1
2
3
4
5
6
72022-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这个方法,我们去看一下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18@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能够避免内存泄漏的原因
1
2
3
4
5
6
7
8
9
10
11@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 粘性事件
我们来看个一个场景
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16MutableLiveData 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了吧,是这样吗
1
2
3
4
5
6
7
8
9
10
11
12
13
14btn.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中只会被回调一次
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public 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); } } }
1
2
3
4
5
6
7
8
9
102022-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
这里就回到了第一小节讲到的一个版本号机制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21private 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,我们使用时一般都是采用空参构造方法。
1
2
3
4
5
6
7
8
9
10
11
12
13public 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++
1
2
3mVersion = 0; mLastVersion = -1;
把判断条件放在这儿
1
2if (observer.mLastVersion >= mVersion) { return; }
这个时候 mLastVersion < mVersion,会继续往下走,这时onChanged就会被回调,观察者获取到值,此时的版本号如下。
1
2
3mVersion = 0; mLastVersion = 0;
所以我们之前讲到的,注册一个观察者会走onStateChanged三次回调,可为什么只回调了一次数据,原因就在这里了,当再次走到这个判断的时候,mLastVersion == mVersion,直接return。
通过版本号机制,就是用来防止组件生命周期变化,导致观察者重复接收多次LiveData的数据。
所以,观察者接收数据的方式有2种:
1 postValue / setValue
2 当组件的生命周期发生改变或者我们第一次注册观察者时
1.2 LiveData事件总线
像实际的开发中,我们使用LiveData不仅仅局限于当前页面的数据展示,包括跨组件、跨页面的通信,同样会使用到LiveData,那么通过LiveData来实现一个事件总线,熟悉使用EventBus的伙伴应该都清楚
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32/** * 事件总线 */ 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对象
1
2
3MutableLiveData<String> liveData1 = LiveDataBus.getInstance().with("key", String.class); liveData1.postValue("1234567");
记不记得之前的小结中,提到的粘性事件,其实官方的LiveData就是存在这个粘性事件的,所以在实际的开发中,这种跳转页面传递参数没有问题,但是如果某些场景就不能使用这种粘性事件,那么官方的LiveData就不能使用了,需要我们自己去处理粘性事件。
前面提到过,粘性事件产生的主要原因就是,在注册观察者的时候,就会导致数据的回调,那么我们是不是可以在数据回调之前,就将观察者的版本号修改成与LiveData的版本号保持一致,是不就可以。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59public 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
1
2owner.getLifecycle().addObserver(wrapper);
我们拿LiveData中observe方法的最后一行代码入手,首先调用了getLifecycle方法
1
2
3
4
5
6
7
8
9
10public interface LifecycleOwner { /** * Returns the Lifecycle of the provider. * * @return The lifecycle of the provider. */ @NonNull Lifecycle getLifecycle(); }
LifeCycle是一个抽象类,获取到的肯定是它的一个子类,我们先从Activity组件入手,看看getLifecycle拿到的是什么。
1
2
3
4
5
6
7
8public 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42@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注册如出一辙。
1
2
3private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>();
3️⃣:如果已经注册过了,就直接return
4️⃣:核心代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24private 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37public 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18static 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️⃣
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19private 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生命周期的同步导致的
看上面这张图,应该也就明白了。
当然,我们这里也只是看到了生命周期的同步跟回调,我在添加观察者的时候,我只是做了状态的初始化,那么后续的触发点在哪呢?
看到下面这张图就能明白了!
在FragmentActivity中,LifeCycleRegistry在每个生命周期回调的时候,都调用了handleLifecycleEvent,在handleLifecycleEvent方法中,其实就拿到了当前组件的生命周期,然后给mState赋值,同时调用了sync同步方法进行生命周期对齐
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public 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对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32public 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篇(最新LiveData LifeCycle源码分析)1 LiveData源码分析2 LifeCycle源码分析的全部内容,更多相关Android进阶宝典内容请搜索靠谱客的其他文章。
发表评论 取消回复