android livedata封装,Android-LiveData原理解析

LiveData

LiveData是一种具有生命周期感知能力的可观察数据持有类。

LiveData可以保证屏幕上的显示内容和数据一直保持同步。

LiveData了解UI界面的状态,如果activity不在屏幕上显示,LiveData不会触发没必要的界面更新,如果activity已经被销毁,会自动清空与Observer的连接,意外的调用就不会发生。

LiveData是一个LifecycleOwner,他可以直接感知activity或Fragment的生命周期。

1.定义LiveData

在项目中,LiveData一般是存放在ViewModel中,以保证app配置变更时,数据不会丢失。

2.使用流程

使用流程其实很简单,就是自定义实现一个Observer观察者,然后在Activity或者Fragment中获取到ViewModel,通过ViewModel获取到对应的LiveData,然后给LiveData添加观察者监听,用来监听LiveData中的数据变化,在Observer的onChanged中使用监听回调数据。

在使用LiveData的时候需要注意,LiveData有两个设置数据的方法,一个是setValue,一个是postValue,setValue只能是在主线程使用,而postValue只能在子线程中使用。

3.核心原理

(1)LiveData.observe(@NonNull LifecycleOwner owner, @NonNull Observer super T> observer)

LiveData添加观察者监听,可以看到LiveData的observe方法,使用了@MainThread注释,表明该观察者监听添加的方法,只能是在主线程中使用,如果不是在主线程中使用,则会抛出异常。

@MainThread

public void observe(@NonNull LifecycleOwner owner, @NonNull Observer super T> observer) {

// 判断是否是在主线程中使用

assertMainThread("observe");

// 如果Activity或者Fragment的状态已经是onDestroy,那么就不可以添加观察者监听

if (owner.getLifecycle().getCurrentState() == DESTROYED) {

// ignore

return;

}

// 将LifecycleOwner和Observer实现对象封装成LifecycleBoundObserver

// 而LifecycleBoundObserver是ObserverWrapper的子类,

// 并且实现了LifecycleEventObserver接口

LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);

// 往LiveData中的mObservers集合添加对应的wrapper对象

// 这样做的目的,就是为了用来在LiveData更新的时候进行通知观察者

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);

}

// LifecycleRegistry.java

@Override

public void addObserver(@NonNull LifecycleObserver observer) {

State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;

ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);

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;

}

boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;

State targetState = calculateTargetState(observer);

mAddingObserverCounter++;

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) {

// we do sync only on the top level.

sync();

}

mAddingObserverCounter--;

}

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;

}

}

// Lifecycling.java

@NonNull

static LifecycleEventObserver lifecycleEventObserver(Object object) {

boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;

boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;

if (isLifecycleEventObserver && isFullLifecycleObserver) {

return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,

(LifecycleEventObserver) object);

}

if (isFullLifecycleObserver) {

return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);

}

if (isLifecycleEventObserver) {

return (LifecycleEventObserver) object;

}

final Class> klass = object.getClass();

int type = getObserverConstructorType(klass);

if (type == GENERATED_CALLBACK) {

List> constructors =

sClassToAdapters.get(klass);

if (constructors.size() == 1) {

GeneratedAdapter generatedAdapter = createGeneratedAdapter(

constructors.get(0), object);

return new SingleGeneratedAdapterObserver(generatedAdapter);

}

GeneratedAdapter[] adapters = new GeneratedAdapter[constructors.size()];

for (int i = 0; i < constructors.size(); i++) {

adapters[i] = createGeneratedAdapter(constructors.get(i), object);

}

return new CompositeGeneratedAdaptersObserver(adapters);

}

return new ReflectiveGenericLifecycleObserver(object);

}

在LiveData添加观察者的时候,因为LifecycleBoundObserver实际上也是实现了LifecycleEventObserver接口的,所以在Lifecycling.lifecycleEventObserver对观察者对象做封装的时候,也是直接返回传入的观察者对象,不做任何的处理

(2)LiveData.LifecycleBoundObserver类

LifecycleBoundObserver中封装了LifecycleOwner对象和Observer对象,并且实现了LifecycleEventObserver接口,根据Lifecycle的原理,其实我们可以知道,LifecycleRegistry.addObserver方法,添加的就是LifecycleEventObserver实现了对象。

所以在Activity使用LiveData,添加观察者,其实其内部最终还是给Activity的LifecycleRegistry添加观察者,然后根据Activity的生命周期的变化对LiveData进行通知。

class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {

// 封装LifecycleOwner实现类对象

@NonNull

final LifecycleOwner mOwner;

LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer super T> observer) {

super(observer);

mOwner = owner;

}

@Override

boolean shouldBeActive() {

// 这个其实就是判断Activity当前状态是否大于等于STARTED,比如RESUMED

return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);

}

@Override

public void onStateChanged(@NonNull LifecycleOwner source,

@NonNull 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);

}

}

// ObserverWrapper内部封装了观察者对象

private 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;

// 如果是不活跃状态

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);

}

}

}

(3)setValue和postValue

@MainThread

protected void setValue(T value) {

// 判断当前线程是否是主线程,如果不是主线程,就抛出异常

assertMainThread("setValue");

mVersion++;

mData = value;

// 通知观察者

dispatchingValue(null);

}

protected void postValue(T value) {

boolean postTask;

synchronized (mDataLock) {

postTask = mPendingData == NOT_SET;

mPendingData = value;

}

if (!postTask) {

return;

}

// 分发执行任务

ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);

}

setValue的通知更新

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, ObserverWrapper>> iterator =

mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {

// 通知观察者,参数是ObserverWrapper类型的对象

// 其实就是LifecycleBoundObserver对象

considerNotify(iterator.next().getValue());

if (mDispatchInvalidated) {

break;

}

}

}

} while (mDispatchInvalidated);

mDispatchingValue = false;

}

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是ObserverWrapper对象,其实现类是LifecycleBoundObserver

// LifecycleBoundObserver内部封装了mObserver观察者

// 在这里调用观察者的onChanged()传入新的数据,就是通知观察者进行更新

observer.mObserver.onChanged((T) mData);

}

postValue的通知更新

postValue的通知更新,其实就是调动任务栈分发任务,而被分发执行的任务实现如下:

private 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()方法,只不过是从子线程切换到了主线程进行执行。做了一次线程的切换。

在postValue方法中,其内部调用的是ArchTaskExecutor的postToMainThread方法。

// ArchTaskExecutor.java

private ArchTaskExecutor() {

mDefaultTaskExecutor = new DefaultTaskExecutor();

mDelegate = mDefaultTaskExecutor;

}

@Override

public void postToMainThread(Runnable runnable) {

mDelegate.postToMainThread(runnable);

}

在这里可以看到mDelegate其实就是DefaultTaskExecutor对象

所以mDelegate.postToMainThread(runnable)其实就是调用了DefaultTaskExecutor.postToMainThread方法。

// DefaultTaskExecutor.java

@Override

public void postToMainThread(Runnable runnable) {

if (mMainHandler == null) {

synchronized (mLock) {

if (mMainHandler == null) {

mMainHandler = createAsync(Looper.getMainLooper());

}

}

}

//noinspection ConstantConditions

mMainHandler.post(runnable);

}

在这里可以看到,mMainHandler其实就是通过主线程的Looper实例创建的Handler对象,所以这里Handler发送消息执行任务,就是在主线程中执行该任务。

(4)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, ObserverWrapper>> iterator =

mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {

considerNotify(iterator.next().getValue());

if (mDispatchInvalidated) {

break;

}

}

}

} while (mDispatchInvalidated);

mDispatchingValue = false;

}

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);

}

LiveData在分发消息的时候,会调用dispatchingValue方法循环分发,当消息分发完成之后,其实并不会退出do-while循环,还会在调用considerNotify方法的内部调用observer.activeStateChanged(false);继续执行第二次dispatchingValue方法,也就是说递归执行,在第二次执行的时候,mDispatchingValue = true,就会执行将mDispatchInvalidated = true,那么就会完成dispatchingValue方法的第二次执行,被直接return,那么considerNotify()方法的执行也就完成,此时就会执行considerNotify之后的if条件,因为在dispatchingValue第二次执行的时候将mDispatchInvalidated设置为了true,就直接break跳出了循环,结束了消息的分发。

但是这样的情况,一般是在存在观察者处于ON_STOP或者已经是ON_DESTROY状态的时候。

如果观察者都是处于onResume,那么这个时候会因为mDispatchInvalidated=false而退出了循环,结束分发。

4.粘性事件

但是如果是先setValue,然后再设置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);

}

因为此时设置Observer的时候,当生命周期发生变化的时候,又会调用回调onStateChanged方法,进而调用activeStateChanged方法

class 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) {

if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {

removeObserver(mObserver);

return;

}

// 这里传入的应该是true

activeStateChanged(shouldBeActive());

}

@Override

boolean isAttachedTo(LifecycleOwner owner) {

return mOwner == owner;

}

@Override

void detachObserver() {

mOwner.getLifecycle().removeObserver(this);

}

}

// 而第一次的时候,mActive默认是false

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();

}

// 变成了true的时候,又会调用一次分发

if (mActive) {

dispatchingValue(this);

}

}

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, ObserverWrapper>> iterator =

mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {

considerNotify(iterator.next().getValue());

if (mDispatchInvalidated) {

break;

}

}

}

} while (mDispatchInvalidated);

mDispatchingValue = false;

}

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之前,已经针对该LiveData设置了一个value,此时添加了观察者,那么又因为生命周期发生了变化,那么该观察者在调用dispatchingValue(this);传入的就不是null,则在do-while循环的if判断中,就会执行if条件,进而调用considerNotify()方法给传入的ObserverWrapper实现类分发消息,那么就会把之前设置的消息分发给了该观察者。

这样的情况就是LiveData的粘性事件。即后注册的观察者接收到了之前LiveData设置的value消息。

那么问题又一次来了,什么时候会触发调用LifecycleBoundObserver的onStateChanged方法呢?

通过LiveData的observe方法进行分析,我们可以知道给LiveData添加观察者的时候,其实就是通过给实现了LifecycleOwner接口的Activity的getLifecycle()方法获取到的LifecycleRegistry对象添加观察者,而LifecycleRegistry中的addObserver方法,就会先满足while条件,然后执行了ObserverWithState.dispatchEvent方法,此时就会调用到了LifecycleBoundObserver.onStateChanged方法

这里为什么会满足while条件呢?calculateTargetState会获取当前Activity生命周期状态的前一个和后一个状态,然后取更小的那个状态,在addObserver的时候,calculateTargetState这里如果activity是onStart的状态,那么calculateTargetState取出的就是CREATED状态,如果activity是onResume的状态,那么这里取出的就是STARTED,不管怎么样都会大于INITIALIZED状态,那么就会满足while条件,此时第二个activity是在onCreate生命周期调用observe方法注册Observer

// LifecycleRegistry.java

@Override

public void addObserver(@NonNull LifecycleObserver observer) {

State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;

ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);

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;

}

boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;

State targetState = calculateTargetState(observer);

mAddingObserverCounter++;

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) {

// we do sync only on the top level.

sync();

}

mAddingObserverCounter--;

}

其实这里个人感觉,应该是在addObserver之后,因为第二个Activity(也就是添加addObserver的)发生了生命周期变化,从onCreate变成了onStart,从onStart变成onResume,此时就会调用moveToState,然后就会调用forwardPass(),然后就会分发消息,因为之前已经postValue或者setValue了,那么在这个LiveData里的mData就不会为null,有消息了,就可以优先分发一次。

满足while条件后,就会调用statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));,这里最终就会调用LifecycleBoundObserver的

@Override

public void onStateChanged(@NonNull LifecycleOwner source,

@NonNull Lifecycle.Event event) {

if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {

removeObserver(mObserver);

return;

}

activeStateChanged(shouldBeActive());

}

这里shouldBeActive(),在Activity的最后的生命周期是onResume的时候,就会满足true,那么此时activeStateChanged()传入的参数就是true,而初始的时候,mActive为false

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);

}

}

此时mActive就会重新赋值为true,那么就会调用dispatchingValue()方法,此时dispatchingValue()的参数传入this,那么就不会为false。

一般常用的粘性事件解决方案,其实就是hook修改mLastVersion的值,让这个值变成与mVersion的值一致,但是如果是在onResume或者onStart的生命周期去添加注册观察者,那么常见的粘性事件解决方案中,因为会调用super.observe(),那么就会因为在LifecycleRegistry.addObserver方法中,满足while条件,从而又会进行LifecycleBoundObserver的onStateChanged方法的回调,这样又会出现粘性事件。这样的情况的解决方案,其实可以hook修改mVersion的值,在注册观察者之前,改成-1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值