首先看一下如下一个简单的使用例子,本文范例使用Kotlin语言进行介绍,Java版的类似,不懂的可以留言问我哈。
// 1.创建LiveData
var loginLiveData:MutableLiveData<LoginEntity> = MutableLiveData<LoginEntity>()
// 2.观察LiveData
loginLiveData.observe(this, Observer {
Log.e(TAG,"loginEntity:$it")
if(!TextUtils.isEmpty(it.token)){
// 成功
Toast.makeText(mContext,"login success", Toast.LENGTH_SHORT).show()
startActivity(Intent(mContext,MainActivity::class.java))
} else {
// 失败
Toast.makeText(mContext,"login failure", Toast.LENGTH_SHORT).show()
}
})
// 3.触发数据改变
loginLiveData.value = response.data
LiveData的使用需要经过以上三个步骤
setValue
方法设置给我们的LiveData
,这时我们的UI也就跟随着改变了。在以上例子中,LoginEntity是我们自己定义的一个实体类,MutableLiveData是LiveData的子类,它很简单,仅是继承了LiveData将LiveData的postValue(T value)
和setValue(T value)
两个方法的访问权限由protected改为public,也就是说它的作用是公开LiveData的两个关键方法postValue(T value)
和setValue(T value)
。通过LiveData的observer方法可以监听到LiveData的数据改变,这个数据改变的触发点就是postValue(T value)
和setValue(T value)
。后面我们从源码的角度出发去分析一下LiveData的工作原理。
我们先把握LiveData的整体工作原理,一些细节放到后面再分析,我们先从LiveData的入口出发,先看看observe
方法的源码:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
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);
}
首先我们看到这方法上面有一个注解@MainThread,它是一个标记注解,没有任何实际作用,仅仅是告诉我们这个方法需要在主线程中调用。这个方法先是判断这个方法是不是在主线程中回调,如果不是将会抛出IllegalStateException("Cannot invoke " + methodName + " on a background" + " thread")
异常,然后创建了一个wrapper用来包裹owner和observer,然后将这个observer放入mObservers
中保存起来,如果已经这个observer已经保存过,并且这个observer没有和当前的owner绑定那么将会识别为同一个observer依附在不同的owner下将会抛出异常,如果已经添加过这个observer并且是同一个owner,那么将会不理睬这次操作,最后将observer和当前的owner的生命周期绑定。
从这个方法的源码中我们知道:
接下来我们看看setValue()
方法,也就是触发数据源改变的地方
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
这个方法将value保存在mData中,接着看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;
}
这个方法通过mDispatchingValue
和mDispatchInvalidated
变量如果当前方法在多个线程中同时访问,那么后面访问的方法会使得do循环体内的代码终止上次执行(break)并重新执行一遍,接下来我们看看considerNotify
方法
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;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}
这个方法中首先判断了传入的observer的激活状态,如果未激活则不响应,如果当前的observer不需要被激活,那么会执行它的activeStateChanged
方法,最终调用observer的onChange
方法将我们在observe方法中保存的data数据传回。
这个是setValue()
方法的执行流程,我们还有一个postValue()
方法,接下来我们看看postValue
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
这个方法通过postToMainThread将数据通知操作切换到了主线程,通过mPendingData变量标记当前主线程是否执行完数据刷新操作,我们看看mPostValueRunnable
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
在主线程执行完成后将mPendingData 置为NOT_SET,如果当前主线程还没处理完这次数据更新,那么后面通过postValue
更新的值将会被忽略,后面调用了setValue()
方法,可以看到postValue
内部将数据的更新操作切换到主线程。
经过以上分析,LiveData的工作原理是内部维持一个Observer的列表,通过observe
方法添加一个观察者,在observe
方法中绑定owner的生命周期,然后在调用setValue
方法的时候通知Observer数据源发生改变,利用的是观察者模式。下面我们看看LiveData是怎么和owner绑定生命周期的。
我们在observe方法中可以看到owner.getLifecycle().addObserver(wrapper);
这里我们先看看这个wrapper类LifecycleBoundObserver.java
LifecycleBoundObserver.java
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@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(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
首先我们看这个类的类结构,发现它实现的GenericLifecycleObserver
接口,该接口是LifecycleObserver 的子类,所以当前的wrapper类实际上是一个LifecycleObserver ,所以可以调用owner.getLifecycle().addObserver(wrapper)
来绑定生命周期。
GenericLifecycleObserver.java
public interface GenericLifecycleObserver extends LifecycleObserver {
/**
* Called when a state transition event happens.
*
* @param source The source of the event
* @param event The event
*/
void onStateChanged(LifecycleOwner source, Lifecycle.Event event);
}
LifecycleBoundObserver 继承于ObserverWrapper.java,我们看看ObserverWrapper.java的activeStateChanged
方法
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
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的激活状态,在当前的激活数量由0变成1的时候会调用onActive()
方法,当激活数量由1变成0的时候会调用onInactive()
方法,我们再看看LifecycleBoundObserver
的shouldBeActive
方法
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
可以发现,LiveData就是在这里判断当前是否需要通知Observer响应数据的改变(回调onChanged()
方法),这里至少要求生命周期为started。接下来我们看看生命周期绑定的最后一个很关键的方法onStateChanged()
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
在上一篇文章【Android AAC】第一篇 Lifecycle的源码解析中我们知道了GenericLifecycleObserver
的onStateChanged()
会在Fragment中回调,可以看到,在onStateChanged
方法中,如果当前的owner的生命周期为DESTORYED,那么将会移除这个观察者,也就是说LiveData会自动解除绑定,而不会造成内存泄漏。如果是其他的生命周期,则会调用activeStateChanged
判断当前的生命周期是否需要响应响应的事件,这里我们回归一下LiveData的considerNotify
方法。
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;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}
这个方法是在setValue方法中会调用的,也就是数据源发生改变的时候会回调这个方法,在这个方法里面判断了当前observer是否需要响应这次数据源的改变。并且根据当前的LiveData的observer激活数量来判断当前LiveData是否被激活或是停止激活,并且会回调LiveData的onActive
和onInactive
方法,不过这两个方法是protected
的,我们可以像MutableLiveData一样通过继承LiveData将onActive
和onInactive
覆盖为public暴露出去。仔细观察发现还有一个observeForever
方法,我们看一下它的源码:
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}
这方法创建的wrapper类为AlwaysActiveObserver
,它表示忽略owner的生命周期,不会自动移除这个观察者,总是会响应数据源的改变,所以,这个方法需要我们手动管理observer的解除绑定操作。
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
经过上面的分析,我们知道LiveData的工作原理如下:
setValue
或者postValue
方法更新数据源,在这个方法中会分发新的数据源到需要每个观察者,同时会判断当前的观察者是否需要响应响应的事件。LifecycleBoundObserver
的onStateChanged
方法判断并移除响应的observer避免了内存泄漏。这个onStateChanged
方法是GenericLifecycleObserver
接口的一个方法,由系统在相应的生命周期中回调。LiveData通过观察者模式和Lifecycle来根据owner的生命周期来对数据源的改变做出响应,其内部在owner处于DESTORYED状态的时候会自动移除响应的observer避免了内存泄漏。