如果文章有问题,请及时指出
LiveData是android的Jetpack中重要部分,是具有生命周期感知的观察者模式。
下面我们来根据源码分析LiveData的原理。
一 LiveData入口
注册观察者
LiveData.java
// key为LiveData的观察者 value 为LiveData的观察者和生命周期绑定对象(LifecycleBoundObserver)
private SafeIterableMap, ObserverWrapper> mObservers =
new SafeIterableMap<>();
// 注册观察者
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
// 这里会把生命周期和观察者进行绑定
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer); // 把观察者存有map中
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;
}
// 注册生命周期观察者,注册时会根据生命周期状态,回调生命周期观察者的change方法
owner.getLifecycle().addObserver(wrapper);
}
生命周期回调:如果注册时生命周期已经经过多次变化,会把以前的生命周期变化事件都回调一遍。所以可能LifecycleBoundObserver.onStateChanged会在注册时调用多次(比如在onResume之后再注册LiveData观察者)。
看下LifecycleBoundObserver,这个类包装了生命周期观察者和我们注册的liveData观察者。
LiveData.java
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer 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;
}
// 调用ObserverWrapper中方法
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
LifecycleBoundObserver的父类ObserverWrapper,其中包含:liveData观察者的版本和当前观察者是否活跃等信息。
private abstract class ObserverWrapper {
final Observer mObserver;
boolean mActive; // mActive是否活跃
int mLastVersion = START_VERSION; // 上一个版本
ObserverWrapper(Observer 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;
boolean wasInactive = LiveData.this.mActiveCount == 0;
// 记录LiveData中活跃观察者的数量
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();
}
// 会调用liveData数据变化
if (mActive) {
dispatchingValue(this);
}
}
}
由上面的可知,在生命周期变化时,会调用LiveData观察者的onChange方法。在观察者注册前上一个消息也会传给观察者。
二 传输数据
异步传输:LiveData.postValue
同步传输:LiveData.setValue
这里就分析setValue,因为postValue就是利用handler处理的。
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
// 更新LiveData的版本号
mVersion++;
mData = value;
// 调用数据传递方法
dispatchingValue(null);
}
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
// 生命周期变化走此处
considerNotify(initiator);
initiator = null;
} else {
// 从map中取出所有观察者,分别调用considerNotify
for (Iterator, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
// setValue走此处
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
private void considerNotify(ObserverWrapper observer) {
// 观察者非活跃不做处理。STARTED和RESUMED状态才能传递消息
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.
// 这里会判断当前生命周期owner的状态是不是在STARTED之后。(会出现这种情况吗???)
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
// 版本控制
if (observer.mLastVersion >= mVersion) {
return;
}
// 更新观察者的版本号
observer.mLastVersion = mVersion;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}
总结:LiveData的观察者能感知生命周期,是因为它内部注册的生命周期观察者,只有在STARTED和RESUMED状态才传递数据。
Observe.onChanged()回调时机: (有版本、是否活跃、LifecycleOwner状态判断)
- 注册Observer时,根据生命周期状态可能回调。
- 生命周期发送变化时,可能回调。
- LiveData.setValue() LiveData.postValue()可能会回调。
粘性事件处理:(**重写方案不好**,父类执行observe时可能回调Observe.onChanged(),消息已经传递了)
如果观察者不想接受之前的消息,可以在注册是把观察者的版本号改成和liveData一样。需要重写LiveData 的public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) ;反射实现观察者和LiveData中版本一样。
三 手写LiveData
package com.example.mylivedata;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.Observer;
import static androidx.lifecycle.Lifecycle.State.DESTROYED;
import static androidx.lifecycle.Lifecycle.State.STARTED;
/**
* 简化的LiveData
* @author 陆小凤
* @date 20/7/31
*/
public class SimplifiedLiveData {
/** 初始化版本信息 */
public static final int INIT_VERSION = -1;
/** 数据 */
private T mData;
/** 观察者集合 */
private List mObservers = new ArrayList<>();
/** 版本信息 */
private int mVersion = INIT_VERSION;
/**
* 修改数据
*
* @param data 数据
*/
@MainThread
public void setValue(T data) {
mData = data;
mVersion++;
dispatchValue();
}
/**
* 传递数据变化
*/
private void dispatchValue() {
for (ObserverWrap wrap : mObservers) {
considerNotify(wrap);
}
}
/**
* 确认通知数据变化
*
* @param wrap 观察组合对象
*/
private void considerNotify(ObserverWrap wrap) {
// 生命周期状态不为RESUMED和STARTED,则不处理
if (!wrap.mLifeOwner.getLifecycle().getCurrentState().isAtLeast(STARTED)) {
return;
}
// 判断版本信息
if (wrap.mLastVersion >= mVersion) {
return;
}
wrap.mLastVersion = mVersion;
wrap.mObserver.onChanged(mData);
}
/**
* 注册观察
*
* @param lifecycleOwner 生命周期Owner对象
* @param observer 观察者
* @param isSticky 是否是粘性 true:粘性;false:非粘性(注册行为以前的数据变化不处理)
*/
@MainThread
public void observe(@NonNull LifecycleOwner lifecycleOwner, @NonNull Observer observer, boolean isSticky) {
if (lifecycleOwner.getLifecycle().getCurrentState() == DESTROYED) {
return;
}
if (isContainObserver(observer)) {
return;
}
ObserverWrap wrap = new ObserverWrap();
wrap.mObserver = observer;
wrap.mLifeOwner = lifecycleOwner;
if (!isSticky) {
wrap.mLastVersion = mVersion;
}
mObservers.add(wrap);
lifecycleOwner.getLifecycle().addObserver(wrap);
}
/**
* 判断观察者是否存在(建议使用map存观察者)
*
* @param observer 观察者
* @return true:存在;false:不存在
*/
private boolean isContainObserver(Observer observer) {
boolean contain = false;
for (ObserverWrap wrap : mObservers) {
if (wrap.mObserver == observer) {
contain = true;
break;
}
}
return contain;
}
/**
* 解注册观察者
*
* @param observer
*/
private void removeObserver(Observer observer) {
mObservers.remove(observer);
}
/**
* 参考Live中LifecycleBoundObserver
* 简化:包含LifecycleOwner对象、观察者对象、版本号
*/
class ObserverWrap implements LifecycleEventObserver {
private LifecycleOwner mLifeOwner;
private Observer mObserver;
private int mLastVersion = INIT_VERSION;
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
if (mLifeOwner.getLifecycle().getCurrentState() == DESTROYED) {
// 解注册LiveData观察者
removeObserver(mObserver);
// 解注册生命周期观察者
mLifeOwner.getLifecycle().addObserver(this);
return;
}
// 当前不是DESTROYED状态的事件都传递
dispatchValue();
}
}
}