JetPack LiveData
1.简介
LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。
详细介绍参阅官方文档
2.基本使用
1.实例化一个LiveData,因为LiveData是抽象类,所以一般实例化其子类MutableLiveData
2.通过setValue、postValue方法设置要观察的对象
3.通过observer(LifecycleOwner,Observer)方法观察要观察的对象
val livedata= MutableLiveData<String>()
livedata.postValue("")
livedata.observe(this, Observer {
})
3.原理分析
1.构造方法
当我们创建一个MutableLivedata对象时,会调用其构造方法,代码如下:
public MutableLiveData() {
super();
}
可以看到调用super()方法,及调用了父类的构造方法,MutableLivedata的父类时LiveData,看一下LiveData的构造方法,代码如下:
static final int START_VERSION = -1;
@SuppressWarnings("WeakerAccess") /* synthetic access */
static final Object NOT_SET = new Object();
private volatile Object mData;
private int mVersion;
public LiveData() {
mData = NOT_SET;
mVersion = START_VERSION;
}
可以看到,构造方法初始了两个变量的值,一个Object类型的mData初始值为一个Object实例对象,一个int类型的mVersion初始值为-1。
2.setValue/postValue方法
接着看setValue方法,代码如下:
@Override
public void setValue(T value) {
super.setValue(value);
}
也是调用父类LiveData的setValue方法,postValue方法也是一样;这里先看一下LiveData的setValue方法,代码如下:
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
四行代码做了四件事:
1.判断是否是主线程,如果不是抛出异常
2.mVersion的值自增,调用setValue方法一次mVersion的值就自增一次
3.将传进来的value赋值给mData对象
4.分发Value
再看一下postValue,先总结一下,postValue用于子线程给LiveData赋值,也就是说,当我们需要再子线程给LiveData赋值时,需要用postValue方法,方法内部帮我们切换到了主线程。代码如下:
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
看最后一行代码,ArchTaskExecutor实际上是一个代理类,代理DefaultTaskExecutor,实际调用的是DefaultTaskExecutor对象中的方法,代码如下:
private ArchTaskExecutor() {
mDefaultTaskExecutor = new DefaultTaskExecutor();
mDelegate = mDefaultTaskExecutor;
}
/**
* Returns an instance of the task executor.
*
* @return The singleton ArchTaskExecutor.
*/
@NonNull
public static ArchTaskExecutor getInstance() {
if (sInstance != null) {
return sInstance;
}
synchronized (ArchTaskExecutor.class) {
if (sInstance == null) {
sInstance = new ArchTaskExecutor();
}
}
return sInstance;
}
@Override
public void postToMainThread(Runnable runnable) {
mDelegate.postToMainThread(runnable);
}
可以看到,通过getInstance方法创建单例对象,然后再构造方法中创建了DefaultTaskExecutor对象,并将赋值给mDelegate,然后调用postToMainThread方法,实际调用的是DefaultTaskExecutor对象的postToMainThread方法。
DefaultTaskExecutor就是继承了TaskExecutor,内部自定义了一个线程池,这里直接看postToMainThread方法
@Override
public void postToMainThread(Runnable runnable) {
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
mMainHandler = createAsync(Looper.getMainLooper());
}
}
}
//noinspection ConstantConditions
mMainHandler.post(runnable);
}
判断mMainHandler是否为null,如果为null就创建一个mMainHandler,createAsync方法内部就是判断不同sdk等级来用不同的方式创建一个持有主线程Looper的Handler,代码如下:
private static Handler createAsync(@NonNull Looper looper) {
if (Build.VERSION.SDK_INT >= 28) {
return Handler.createAsync(looper);
}
if (Build.VERSION.SDK_INT >= 16) {
try {
return Handler.class.getDeclaredConstructor(Looper.class, Handler.Callback.class,
boolean.class)
.newInstance(looper, null, true);
} catch (IllegalAccessException ignored) {
} catch (InstantiationException ignored) {
} catch (NoSuchMethodException ignored) {
} catch (InvocationTargetException e) {
return new Handler(looper);
}
}
return new Handler(looper);
}
然后通过post方法执行runnable,那么这个runnable是什么时候创建的,就是在我们创建LiveData对象的时候创建的,代码如下:
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};
可以看到,最终还是执行了setValue方法,不过这时候已经切换到主线程执行了。
3.分析setValue方法中的dispathValue方法
直接看代码:
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默认为false,会直接走到do{}while()循环里面,然后initiator第一次为null,会走else,else里面就是遍历mObservers,获取我们observer()方法中添加的observer,然后执行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;
observer.mObserver.onChanged((T) mData);
}
这里的observer其实是我们observer()方法中的的LifecycleBoundObserver,observer()方法代码如下:
@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);
}
上面的代码中,先判断当前的生命周期是否是destory,如果是就return,如果不是创建了LifecycleBoundObserver对象,并将lifecycleOwner和我们创建的匿名内部类Observer传递进去,LifecycleBoundObserver实现了LifecycleEventObserver,并在内部持有我们传进去的Observer,代码如下:
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
@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();
}
}
从上面的代码可以看到,LifecycleBoundObserver继承了ObserverWrapper,实现了LifecycleEventObserver,并实现了onStateChanged方法,看一下ObserverWrapper做了什么,代码如下:
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
持有了我们传递进来的observer并赋值给mObserver,并初始化了mLastVersion为-1。
接下来执行
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
将observer为key,LifecycleBoundObserver为value存入mObservers,并调用
owner.getLifecycle().addObserver(wrapper);
使LifecycleBoundObserver能观察到activity、fragment的生命周期
然后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;
observer.mObserver.onChanged((T) mData);
}
可以看到如果不符合生命周期就不执行,如果observer.mLastVersion >= mVersion就不执行,mVersion的值是什么时候自增的呢,在setValue方法执行的时候(这里会有个问题,就是我们先setValue,再注册观察者,后观察者也会收到改变的值,在改造事件总线的时候会遇到)
接下来就是执行
observer.mObserver.onChanged((T) mData);
从LifecycleBoundObserver获取我们的observer,调用了onChanged方法,就能观察到数据变化了。