Android Jetpack 架构之 LiveData 源码分析
1. 认识 LiveData
1.1. LiveData 介绍
引用官方介绍:
LiveData 是一个可观察的数据存储类,实际上就是一个消息组件,用于数据的传递。和一般的可观察者不同的是,LiveData 是具有生命周期感知能力的,意思是它关心其它应用组件的生命周期,如:Activity,Fragment 和 Service。这种感知能力意味着 LiveData 只会更新那些生命周期处于活跃状态的应用组件观察者。
1.2. 使用 LiveData 的优势
引自官方介绍:
- 与生命周期组件关联,当生命周期组件销毁后,LiveData 会进行自动清理,所以,不会出现内存泄漏。
- 当 Activity 或 Fragment 牌非活跃状态时,LiveData 不会为这些处于非活跃状态(后面会详细分析活跃或非活跃状态)的观察者发送数据,所以,不会导致非活跃的 Activity 或 Fragment 出现崩溃。
- 不需要使用者手动处理生命周期,LiveData 会根据观察者不同的生命周期变化而进行相应数据的更新。
- 可以全局共享同一个 LiveData 来实现一些特殊的功能。
- Room 数据库原生支持返回 LiveData 封装后的数据,方便 LiveData 开发者操作数据库。
1.3. 传统消息组件存在的问题
传统的消息处理组件对开发的要求较高,对于一些经验欠缺的工程师来说,很容易写出带有 Bug 的代码,导致内存泄漏,甚至崩溃。如:系统提供的 Handler 组件,由于队列中未处理消息持有引用问题,消息处理过程中页面关闭的内存泄漏问题等等;再如:Github 上有名的 Eventbus 消息组件,弱关联导致代码使用混乱难定位问题,需要开发者自己处理生命周期问题等等。
2. LiveData 总体结构及各自职责
2.1. LiveData 整体架构
上图是 LiveData 的一个整体架构图,现在我们来对架构中所涉及到的主要类职责进行说明。
2.2. LiveData
LiveData 是一个抽象类,也是 LiveData 整个设计的核心类。它实际上是一个 Observeable 对象,主要负责数据版本的维护、Observer 对象的管理以及消息的分发等工作。
数据版本的维护指的是 LiveData 使用版本来对发送的消息进行维护,每发送一次消息,版本自加 1 。这种做的好处是当对应的消息观察者从不活跃状态进入活跃状态时,由于每个观察者也使用了一个版本来维护自己最后一次所接收到的消息的版本,LiveData 在发送数据更新时,只需要拿自己最后更新的版本号与观察者所持有的版本号进行比对,就能知道是否需要把最后一次更新的数据发送给观察者。
Observer 对象的管理说的是 LiveData 是一个 Observable 对象,其对象里持有一个 Observer 集合对象,用以对所有的观察者进行管理。当有新消息传递或者相应的组件生命周期发生变化后,就会通过遍历集合,并通过观察者所关联的生命周期组件的状态来更新满足更新状态的观察者。
消息分发指的就是对消息进行集中处理,整个 LiveData 实现中的数据处理都是在同一个地方集中处理的。
2.3. MutableLiveData
public class MutableLiveData<T> extends LiveData<T> {
public MutableLiveData(T value) {
super(value);
}
public MutableLiveData() {
super();
}
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
MutableLiveData 是 LiveData 的一个实现类,它里面其实什么也没有做,只是暴露了两个传递消息的方法,方法的真实实现还是在 LiveData 里面。LiveData 中有很多其它的一些实现类,而这个 MutableLiveData 应该是最简单的一个实现类,由于在 Kotlin 中所有的对象会分为 mutable 和 immutable 两种类型,而默认不带前缀的是 immutable 类型,意思是赋值之后,对应的值不能被改变。此类更多的意思是表示该类是一个可变的 LiveData 对象,也就是可能重复为消息对象赋值。像下面这种情况,就不行。
val text: LiveData<String> = MutableLiveData("aaaa")
text.value="bbb" // compile error
2.4. LifecycleBondObserver
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ignore others ........
}
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
ignore others ........
}
LifecycleBoundObserver 是一个 Observer 对象,继承自 ObserverWrapper 类。这个 ObserverWrapper 类是一个 Observer 的包装类。它里面只有三个变量,一个是 observer 表示持有 observer 对象;一个是 mActive 表示当前 Observer 对应的 LiveData 所关联的 LifecycleOwner 的状态,其实就是处于活跃状态或不活跃状态;第三个变量 mLastVersion 表示当前 Observer 的最后更新的版本。
LifecycleBoundObserver 是一个将 LifecycleOwner 与订阅了 LiveData 对象的 Observer 封装在一起的一样类。这样做的好处是,当 LiveData 的发送新的数据再对消息进行分发时,直接可以判断 Observer 所关联的 LifeOwner 的生命周期状态来决定是否要将数据发送给 Observer 处理。
说到这里,其实有一个比较重要的东西需要说明一下,就是所谓的 LiveData 是具有生命周期感知的消息组件,其本质是因为 订阅了 LiveData 消息的观察者与具体的具有生命周期特性的这些组件关联在了一起,而 LiveData 在分发消息时,会根据不同的 Observer 对象所关联的 LifecycleOwner 的状态,来决定是否为该 Observer 分发数据而已。其 LiveData 对象本身只是一个简单的消息分发的类。
2.5. ComponentActivity 及其子类
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
LifecycleOwner,
ViewModelStoreOwner,
HasDefaultViewModelProviderFactory,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner {
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}
ignore ....
}
ComponentActivity 是一个继承了 LifecycleOwner 的具有生命周期属性的 Activity 组件。每个 ComponentActivity 及其子类都持有一个 LifecycleRegistry 对象,用于专门处理 ComponentActivity 的生命周期事件及管理订阅了生命周期组件的观察者 Observer。ComponentActivity 并不直接管理自己的生命周期,而是通过 ReportFragment 对象来进行管理及分发的。
2.6. ReportFragment
public class ReportFragment extends Fragment {
public static void injectIfNeededIn(Activity activity) {
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();
}
}
private ActivityInitializationListener mProcessListener;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatchCreate(mProcessListener);
dispatch(Lifecycle.Event.ON_CREATE);
}
@Override
public void onStart() {
super.onStart();
dispatchStart(mProcessListener);
dispatch(Lifecycle.Event.ON_START);
}
....
ReportFragment 对象用于对 ComponentActivity 生命周期进行具体管理及事件分发的类。每一个 ComponentActivity 在 onCreate 方法里都会创建并将 ReportFragment 对象注册到其中。这里的设计还是比较巧妙的,使用一个 Fragment 来对 Activity 的生命周期进行管理,我们知道 activity 对应的生命周期发生变化后,fragment 也会收到相应的回调。
这种设计我是在 Glide 中有见到过,我们知道 Glide 也是一个具有生命周期感知能力的框架,当我们在创建 Glide 时,使用的是 activity 对象时,当 activity 不可见时,Glide 就会停止处理图片。
从上面的代码中可以看出 activity 所对应的几种生命周期都在 ReportFragment 中得到了重写,而且里面都有一个dispatch(Lifecycle.Event.XXX)
函数,该函数主要是做生命周期事件分发用的。该函数把生命周期转发给 LifecycleRegistry 对象来进行处理。
其实,ReportFragment 除了直接绑定具体的 Activity 做相应的生命周期分发以外,还有一个任务是和 ProcessLifecycleOwner 对象有关的。大家会不会觉得奇怪,在 ReportFragment 中的 onActivityCreated()
,onStart()
和 onResume()
三个方法中怎么都调用了两个分发事件的方法?先卖个官子吧,在对 ProcessLifecycleOwner
进行分析时,我再来讲这个问题。
2.7. ProcessLifecycleOwner
public class ProcessLifecycleOwner implements LifecycleOwner {
private final LifecycleRegistry mRegistry = new LifecycleRegistry(this);
ActivityInitializationListener mInitializationListener = new ActivityInitializationListener() {
public void onCreate() {
}
public void onStart() {
ProcessLifecycleOwner.this.activityStarted();
}
public void onResume() {
ProcessLifecycleOwner.this.activityResumed();
}
void activityStarted() {
++this.mStartedCounter;
if (this.mStartedCounter == 1 && this.mStopSent) {
this.mRegistry.handleLifecycleEvent(Event.ON_START);
this.mStopSent = false;
}
}
void activityResumed() {
++this.mResumedCounter;
if (this.mResumedCounter == 1) {
if (this.mPauseSent) {
this.mRegistry.handleLifecycleEvent(Event.ON_RESUME);
this.mPauseSent = false;
} else {
this.mHandler.removeCallbacks(this.mDelayedPauseRunnable);
}
}
}
void activityPaused() {
--this.mResumedCounter;
if (this.mResumedCounter == 0) {
this.mHandler.postDelayed(this.mDelayedPauseRunnable, 700L);
}
}
void activityStopped() {
--this.mStartedCounter;
this.dispatchStopIfNeeded();
}
void attach(Context context) {
this.mHandler = new Handler();
this.mRegistry.handleLifecycleEvent(Event.ON_CREATE);
Application app = (Application)context.getApplicationContext();
app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
ReportFragment.get(activity).setProcessListener(ProcessLifecycleOwner.this.mInitializationListener);
}
public void onActivityPaused(Activity activity) {
ProcessLifecycleOwner.this.activityPaused();
}
public void onActivityStopped(Activity activity) {
ProcessLifecycleOwner.this.activityStopped();
}
});
}
ProcessLifecycleOwner 也是一个具有生命周期感知的的对象,但有点奇怪的是,在 Android 中不是只有 Activity,Service 和 Fragment 等对象才有生命周期的概念么?这个 ProcessLifecycleOwner 并没有继承这几个类,怎么也是具有生命周期感知的呢?
带着上面的疑问,我们来分析一下 ProcessLifecycleOwner 是如何实现生命周期感知功能的。
public class ProcessLifecycleOwnerInitializer extends ContentProvider {
@Override
public boolean onCreate() {
LifecycleDispatcher.init(getContext());
ProcessLifecycleOwner.init(getContext());
return true;
}
ProcessLifecycleOwner 是在 ProcessLifecycleOwnerInitializer 对象的 onCreate() 方法中初始化的,ProcessLifecycleOwnerInitializer 继承自 ContentProvider,我们知道在 Android 系统在进行启动时,ContentProvider 往往是最先被注册到系统中的。可以看出 ProcessLifecycleOwner 对象也是在系统刚启动的时候就被创建了。
private static final ProcessLifecycleOwner sInstance = new ProcessLifecycleOwner();
上面的代码可以看出,ProcessLifecycleOwner 是一个全局静态类,其对象只能通过 get()
方法来获取。在 ProcessLifecycleOwner 的 init()
方法中,又调用了 attach()
方法。在 attach()
方法中,调用了 Application 对象的 registerActivityLifecycleCallbacks()
方法,这是一个全局的 Activity 生命周期回调的监听。
app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
ReportFragment.get(activity).setProcessListener(mInitializationListener);
}
@Override
public void onActivityPaused(Activity activity) {
activityPaused();
}
@Override
public void onActivityStopped(Activity activity) {
activityStopped();
}
});
}
在 onActivityCreated()
回调方法中,mInitializationListener 被注册到了 ReportFragment 对象里。我们回到 ReportFragment 对象里,可以看到在其 onActivityCreated()
,onStart()
和 onResume()
方法中都调用了相应的 dispatchXXX()
函数,在这个函数里又回调了 mInitializationListener
对象里对应的回调函数。
兜了一个圈,发现 ProcessLifecycleOwner 的生命周期也是通过 ReportFragmnet 来管理的,当 Activity 的生命周期发生变化后,会先调用 ReportFragment 对应的生命周期函数,而在 ReportFragment 对应生命周期函数中又调用了 ProcessLifecycleOwner 对象中的 mInitializationListener 回调函数。而 mInitializationListener 其实就是
ProcessLifecycleOwner 所对应的生命周期。
ActivityInitializationListener mInitializationListener =
new ActivityInitializationListener() {
@Override
public void onCreate() {
}
@Override
public void onStart() {
activityStarted();
}
@Override
public void onResume() {
activityResumed();
}
};
ProcessLifecycleOwner 的生命周期说明白了。我直接给出结论吧:ProcessLifecycleOwner 其实是一俱全局的具有生命周期感知能力的 LifecycleOwner 对象,我们可以在注册 LiveData 对象的时候,传入这个 ProcessLifecycleOwner 对象,以后只要 Activity 页面发生变化后,都会通过 ReportFragment 回调到 mInitializationListener 对应的回调方法中,在通过 mRegistry 对象 handleLifecycleEvent()
方法来处理这个事件。
有没有对这个 mInitializationListener 感到奇怪,怎么这里只有三个生命周期回调方法,而且 onCreate()
方法里还没有调用任何方法?
上面我们说了 ProcessLifecycleOwner 是一个全局的具有生命周期感知能力的对象,它的生命周期其实是和 Application 是一样的。也就是说只要应用还在运行,它的状态永远都不会大于 ON_RESUME 的状态,而如果应用退出了,它也就不存在了。第二个问题是,onCreate()
里怎么没有调用任何方法呢?
void attach(Context context) {
mHandler = new Handler();
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
...
}
原来是在初始化的时候就已经执行过了 ON_CREATE 状态了。而 ProcessLifecycleOwner 又是一个全局静态类,以后都不会再创建了,所以回调方法中就不再需要对 onCreate()
方法进行处理了。
这里有个问题是:ProcessLifecycleOwner 对象既然是一个全局的生命周期感知对象,它的生命周期事件是通过 mInitializationListener 来实现的。那么,订阅了它的观察者又保存在哪里呢?我们先看一下这个全局对象在开发中的使用。
liveData.observe(ProcessLifecycleOwner.get(), Observer { })
进入 observe 方法中,可以看到下面这个调用:
owner.getLifecycle().addObserver(wrapper);
从这个调用可以看出,所有的 Observer 对象都保存在了具有生命周期感知能力对象中的 LifecycleRegistry 对象中,我们刚好在 ProcessLifecycleOwner 里看到了 mRegistry 对象。
private final LifecycleRegistry mRegistry = new LifecycleRegistry(this);
到这里这个全局的具有生命周期感知能力的对象就已经讲完了。我们来看一下大概的调用情况吧(以 onStart 为例)
2.8. LifecycleRegistry
public class LifecycleRegistry extends Lifecycle {
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
new FastSafeIterableMap<>();
private State mState;
private final WeakReference<LifecycleOwner> mLifecycleOwner;
ignore ........
}
LifecycleRegistry 是一个带生命周期对象(如:activity,fragment)的管理类,主要负责对订阅了生命周期对象的 Observer 对象进行管理和维护。这里的 observer 和注册 LiveData 对象的 observer 本质上是同一个类,它是在订阅 LiveData 时一并注册到 LiveData 所管理的 mObservers 和 LifecycleRegistry 所管理的 mObserverMap 中的。
2.9. ObserverWithState
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 = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
ObserverWithState 是一个封装了 LifecycleEventObserver 和 mState 两个对象的类。这个对象是 LifecycleRegistry 对象中对订阅了具有生命周期感知能力对象的进行管理的一个封装类。其中,LifecycleEventObserver 对象就是 LifecycleBoundObserver 对象。而这里的状态又是什么呢?
其实这个 mState 对应的就是当前 Observer 所绑定的 LifecycleOwner 当前的生命周期,如果发生变化,这个值也会被修改。而这个状态在更新后,是和 LifecycleOwner 所对应的 LifecycleRegistry 中的 mState 的值是一样的。
走到这里,涉及 LiveData 整个架构中的主要对象就已经都讲完了。下面我通过一个流程图把这个简单的窜一下。
3. Lifecycle 工作原理相关
在看源码的时候,有没有感到头大,LifecycleRegistry 在更新生命周期的时候,并没有直接将当前的生命周期事件对象赋值给对应的 Observer 对象,而是出现了一个 upEvent(State state)
,downEvent(State state)
,getStateAfter(Event event)
等用来更新具体 Observer 对象的生命周期的。在这个单元我们不妨来分析一下和 Lifecycle 更新机制相关的一些东西吧。
3.1. Event 和 State
在分析之前,先要弄清楚两个基础的生命周期对象,如下:
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY
}
···
这里的 Event 对应的就是页面的生命周期,当具体的生命周期被触发了,就会使用对应的事件来进行分发。而 State 表示页面的一个状态,是一种包含关系。
DESTROYED
页面调用 ON_DESTROY 后的状态,会在调用之前修改其状态。
INITIALIZED
当 Activity 被创建了,但 ON_CREATE 还未被调用时的状态。
CREATED
页面调用了 ON_CREATE 或者 ON_STOP 后的状态。
STARTED
页面调用了 ON_START 或者 ON_PAUSE 后的状态。
RESUMED
页面调用了 ON_RESUME 后的状态。
上图画的是生命周期事件和状态的对应关系,看着会更直观一些。当对应的生命周期执行完成后,所对应的区域就是当前的状态。如:ON_START 执行后,就是 STARTED 状态。
3.2. Lifecycle 状态更新
上面讲的都相对理论一些,这一节我们直接面向源码,从一次事件的变化来看一下具体的处理流程。
这里从 LifecycleRegistry 的 addObserver()
方法说起。
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
// 将 observer 与其关联的 LifecycleOwner 的状态进行封装,默认给初始值
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
// 将 observer 对象存储到 mObserverMap 中进行管理和状态维护
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {
// 说明已经订阅过了,就不在重复执行相应的状态更新了
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}
// 该值主要是判断是否需要同步已经订阅了 observer
// 的状态,但这个值有点奇怪,如果不考虑多线程,这个参数没什么必要,如果考虑多线程,
// 这里明显又没有做多线程的处理
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
// 正常添加的话,该值就是 LifecycleRegistry 中 mstate 的值
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
// 这个循环主要是将先加入的 observer 与当前 LifecycleRegistry 的 mstate 进行比较,
// 如果状态小于 mState,就会依次按照 Event 事件的先后顺序依次对新加入的 observer 进行更新,
// 并分发事件给 Observer,Observer 最终是否会收到 LiveData 的更新数据,取决于双方的数据版本号
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}
if (!isReentrance) {
// 这个同步方法的作用主要是对已经订阅了 LifecycleOwner 事件的 Observer 对象进行状态同步,
// 也就是同步到和 LifecycleRegistry 的 mState 状态一致。
sync();
}
mAddingObserverCounter--;
}
当 LiveData 被订阅之后,就会调用管理 LifecycleOwner 生命周期对象 LifecycleRegistry 中的 addObserver()
方法,这个方法里做了下面几件事情:
- 给 Observer 对象绑定 mState 对象,并赋予初始状态存入到集合中。
- 更新新加入进入的 Observer 对应的 mState 状态,这里主要是和当前的 LifecycleRegistry 中的 mState 对象比较后,依次按照 State 中的状态对 Observer 进行 Event 生命周期事件分发。
- 对之前已经订阅了 LifecycleOwner 的 Observer 对象进行状态刷新,也就是将 Observer 对象和 LifecycleRegistry 中的状态进行同步。
接下来看一下,当页面的生命周期改变后,具体是怎么处理的。这里拿事件执行了 ON_RESUME 为例来分析一下更新过程。
我们可以直接从 ReportFragment 中的 onResume()
看起。
@Override
public void onResume() {
super.onResume();
dispatchResume(mProcessListener);
dispatch(Lifecycle.Event.ON_RESUME);
}
这里 dispatch()
方法就是分发生命周期事件的方法。dispatchResume()
是用于为订阅了全局生命周期事件的 Observer 分发事件的方法。
private void dispatch(Lifecycle.Event event) {
Activity activity = getActivity();
// 这里只是为了兼容老的thsg版本用的,LifecycleRegistryOwner
// 在新的 Lifecycle 组件中被标记为了 @Deprecated
if (activity instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
}
if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
}
可以看到这里直接调用到了当前生命周期的管理类 LifecycleRegistry 的 handleLifecycleEvent(event)
方法。
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
这个方法里只做了一件事情,就是将当前事件转换为对应的 State 后,就直接调用了 moveToState()
方法。
private void moveToState(State next) {
if (mState == next) {
return;
}
// 将 lifecycleRegistry 中 mState 对象更新y最新的状态
mState = next;
// 这里的判断与 addObservers() 方法中的判断是一致的。
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
// we will figure out what to do on upper level.
return;
}
mHandlingEvent = true;
// 刷新已经订阅了生命周期事件的所有 Observers
sync();
mHandlingEvent = false;
}
这个方法主要是对已经订阅了当前生命周期事件的所有 Observers 对象进行刷新。对单个 Observer 事件的刷新主要是调用了 ObserverWithState 中的 dispatchEvent()
方法。
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
这个方法首先将当前事件转换为了对应的 State 状态。这里我讲一下 min(mState, newState)
这个方法具体是怎么比较的。
static State min(@NonNull State state1, @Nullable State state2) {
return state2 != null && state2.compareTo(state1) < 0 ? state2 : state1;
}
这个比较方法的核心主要是 Enum 对象的比较方法 compareTo()
,每个 Enum 对象中都有一个 ordinal 字段,这里的比较操作主要是 ordinal 值的比较。默认情况下,Enum 中对象的 ordinal 是从 0 开始的,依次进行赋值。也就是说上面的对象在比较的时候,是小于下面的对象的。
接下来就调用了 ```onStateChanged()`` 方法。
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
如果当前状态是 DESTROYED,说明该生命周期对象已经被销毁了,对应的 observers 都会被清除。如果是其它状态,就调用 activeStateChanged(shouldBeActive())
方法。
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
mActive = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();
}
if (mActive) {
dispatchingValue(this);
}
}
如果状态一样就直接返回。如果当前 Observer 对象所订阅的 LiveData 对象中的其它所有 Observer 对象都是未激活状态,也就是 mActiveCount 值等于 0,而当前又是激活分发的又是激活状态的话,就会回调 LiveData 对象的 onActive()
方法。相反,如果当前分发的是非激活状态,而更新了 mActiveCount 值后,mActiveCount 值为 0 ,则回调 LiveData 的 onInactive()
方法。这里的两个方法只有在继承了 LiveData 并覆写后,才会收到调用,LiveData 本身是空实现。
最后,如果分发的是激活状态的话,就会调用 dispatchingValue()
方法来分发 LiveData 中的值。
void dispatchingValue(@Nullable ObserverWrapper initiator) {
// 同时只能有一个调用源执行该方法,当然,如果在多线程情况下,是有问题的
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
// initiator 只有在调用 setValue 更新 LiveData 值的时候,才会为 null
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;
}
首先,该方法同时只能被调用一次。只有在调用 setValue 更新 LiveData 值的时候,initiator 才会为 null,而我们这里是通过生命周期改变后调用的,所以,是不为 null 的,这里调用 considerNotify(initiator)
方法。
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
该方法也比较简单,只是做了一些必要的判断。如果当前 observer 对象的 mLastVersion 值大于等于 mVersion,说明当前 observer 对象已经是最新的值了,不需要再次更新。如果数据版本小于 LiveData 对象的 mVersion,则将当前 LiveData 最新的版本赋值给当前 observer 对象,并将最新的值传递给 observer 对象,进行更新。
到这里整个由事件改变后,LiveData 数据的更新过程就已经结束了。
4. LiveData 订阅及数据更新
4.1. LiveData 订阅过程
这里再来窜一下 LiveData 的订阅过程。
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
return;
}
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;
}
owner.getLifecycle().addObserver(wrapper);
}
如果订阅当前 LiveData 对象所指定的生命周期感知对象的状态已经是 DESTROYED,就直接返回。接下来使用 LifecycleBoundObserver 对 observer 进行包装,这个对象里将生命周期对象 mOwner,观察者对象 mObserver,当前是否处于激活状态 mActive 以及当前数据的版本 mLastVersion 绑定在了一起。并将该包装对象添加到了 LiveData 管理 Observer 对象的集合类中。同时这里还将包装对象添加到了 LifecycleRegistry 中用于添加对事件改变的监听。
订阅过程挺简单的,接下来我们再来看看对 LiveData 设置值之后的过程。
4.2. LiveData 数据更新
LiveData 的数据更新主要是通过 setValue()
方法和 postValue()
方法来进行更新的。而 postValue()
方法和 setValue()
的区别主要是:postValue()
方法主要是用于子线程的数据更新,在方法里有切换到主线程去执行任务的。所以,这里只需要看 setValue()
方法就可以了。
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
这里只是更新了 LiveData 的版本和数据后,就直接调用到 dispatchingValue(null)
方法了。
@SuppressWarnings("WeakerAccess") /* synthetic access */
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;
}
这个方法上面讲过,只不过上面传递的是有值的情况,这里传的是 null,所以我们走到了另外一个分支。实际上也没啥就是遍历了当前所有订阅了 LiveData 对象的集合类,依次对每个订阅对象进行数据的分发。
这里有一个问题可以研究一下,就是 mDispatchingValue 和 mDispatchInvalidated 两个对象是怎么工作的?当第一次调用 dispatchingValue()
方法的时候,mDispatchingValue 为 true, mDispatchInvalidated 为 false,所以 do ... while
循环只会被执行一次,且 for 循环
会被执行完成。而如果还在 for 循环
的时候该方法又被调用了,for 循环
就会被停止,且新调用的方法也得不到执行。感觉是一种多线程的保护,但看上去很鸡肋。
5. 结语
好了,到这里所有关于 LiveData 的分析就已经讲完了,整个源码分析并不是很难。LiveData 本身的实现比较简单,只是如何具备生命周期感知能力的这一部分关于 lifecycle 及其交互的实现稍稍复杂一点,要理清楚他们之间的关系及交互。整个架构的设置还是很优秀的,各自的职责非常清晰,生命周期事件与相应状态及其更新方式的设计也非常的巧妙,整个架构我用一个双观察者的事件驱动模式
来概括。