网站设计 优帮云,中国兼职设计师网,规模以上工业企业总产值,武义县网站制作时人不识凌云木#xff0c;直待凌云始道高 一#xff0c;基本使用
基本使用请看文章Android--Jetpack--LiveData-CSDN博客 二#xff0c;MutableLiveData
首先说一下我们为什么要用MutableLiveData呢#xff0c;来看看LiveData的源码#xff1a;
public abstract class…时人不识凌云木直待凌云始道高 一基本使用
基本使用请看文章Android--Jetpack--LiveData-CSDN博客 二MutableLiveData
首先说一下我们为什么要用MutableLiveData呢来看看LiveData的源码
public abstract class LiveDataT {。。。。protected void postValue(T value) {boolean postTask;synchronized (mDataLock) {postTask mPendingData NOT_SET;mPendingData value;}if (!postTask) {return;}ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);}MainThreadprotected void setValue(T value) {assertMainThread(setValue);mVersion;mData value;dispatchingValue(null);}
}
setValue 和postValue 都是protected方法外面拿不到
同时这里的setValue使用了注解MainThread 说明只能在主线程发送数据
再来看看MutableLiveData的源码
public class MutableLiveDataT extends LiveDataT {/*** Creates a MutableLiveData initialized with the given {code value}.** param value initial value*/public MutableLiveData(T value) {super(value);}/*** Creates a MutableLiveData with no value assigned to it.*/public MutableLiveData() {super();}Overridepublic void postValue(T value) {super.postValue(value);}Overridepublic void setValue(T value) {super.setValue(value);}
}
这是它的全部代码只是把postValue和setValue这两个方法公开了。其余的都是继承LiveData。
这就是我们为什么使用MutableLiveData的原因。
三消息发送源码分析
setValue和postValue都是发送数据的但是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);
}
通过ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);切换到了主线程再来看看mPostValueRunnable
private final Runnable mPostValueRunnable new Runnable() {SuppressWarnings(unchecked)Overridepublic void run() {Object newValue;synchronized (mDataLock) {newValue mPendingData;mPendingData NOT_SET;}setValue((T) newValue);}
};
最终还是调用了setValue所以说postValue只是多了一个线程切换的操作。
所以我们重点看下setValue的源码
MainThread
protected void setValue(T value) {assertMainThread(setValue);mVersion;mData value;dispatchingValue(null);
}
首先看看assertMainThread(setValue):
static void assertMainThread(String methodName) {if (!ArchTaskExecutor.getInstance().isMainThread()) {throw new IllegalStateException(Cannot invoke methodName on a background thread);}
}
这个方法的作用就是检查是不是在主线程不在主线程就抛异常。
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 {for (IteratorMap.EntryObserver? super T, ObserverWrapper iterator mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {considerNotify(iterator.next().getValue());if (mDispatchInvalidated) {break;}}}} while (mDispatchInvalidated);mDispatchingValue false;
}
上面都是判断主要来看这行代码
for (IteratorMap.EntryObserver? super T, ObserverWrapper iterator mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {considerNotify(iterator.next().getValue());if (mDispatchInvalidated) {break;}
}
这里有个mObservers我们来看看这是什么
private SafeIterableMapObserver? super T, ObserverWrapper mObservers new SafeIterableMap();
这是一个key为Obsercervalue为ObserverWrapper的map集合。
我们再来看看mObservers是在什么时候添加元素的
MainThread
public void observe(NonNull LifecycleOwner owner, NonNull Observer? super T observer) {assertMainThread(observe);if (owner.getLifecycle().getCurrentState() DESTROYED) {// ignorereturn;}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);
}
是在observe方法中添加的先看看observe什么时候调用
Observer observer new ObserverString() {Overridepublic void onChanged(String o) {System.out.println(yz---o);txt.setText(o);}
};
//获取viewmodule
model new ViewModelProvider(this).get(MyViewModel.class);
model.getCount().observe(this,observer);
在上篇使用的时候我们会在Activity中这样调用observe第一个参数是Activity第二个参数是自己定义的观察者。
然后我们再回到observe方法中首先检查了是不是在主线程然后判断如果当前Activity的状态是不可用状态就返回。如果是可用状态就将Activity和观察者包装成wrapper并且以观察者为keywrapper为value添加进mObservers集合。如果这个集合里面不是空的并且不是重复的observer 就执行owner.getLifecycle().addObserver(wrapper);我们在Android--Jetpack--Lifecycle详解-CSDN博客Android--Jetpack--Lifecycle详解-CSDN博客Android--Jetpack--Lifecycle详解-CSDN博客中讲过这个就会添加进观察者集合中。
了解了mObservers之后我们再回到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 {for (IteratorMap.EntryObserver? super T, ObserverWrapper iterator mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {considerNotify(iterator.next().getValue());if (mDispatchInvalidated) {break;}}}} while (mDispatchInvalidated);mDispatchingValue false;
}
这里会执行considerNotify(iterator.next().getValue());继续看它的源码
private void considerNotify(ObserverWrapper observer) {if (!observer.mActive) {return;}// Check latest state b4 dispatch. Maybe it changed state but we didnt 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 weve 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);
}
将上面我们包装的ObserverWrapper传了进来。
首先判断这个观察者是不激活状态就返回不执行
然后就到了这句代码
if (observer.mLastVersion mVersion) {return;
}
mVersion刚才出现过我们看看mVersion
public LiveData() {mData NOT_SET;mVersion START_VERSION;
}
在我们创建new MutableLiveData()的时候会给mVersion赋值START_VERSION-1
然后我们setValue的时候mVersion会1.
之后就会走到considerNotify(iterator.next().getValue())方法中。
observer.mLastVersion的初始值
static final int START_VERSION -1;
int mLastVersion START_VERSION;
所以我们setValue的时候会走到dispatchingValue方法中然后会走到considerNotify中接下来就到了 observer.mObserver.onChanged((T) mData)方法这时就会回调observer的api把消息发送出来了。 四数据倒灌和粘性问题
正常我们的执行顺序是new LiveData--绑定observer--setValue执行onChanged
但是当我们跨Activity的时候可能执行顺序是这样的
new LiveData--setValue执行onChanged--绑定observer
这样会有什么问题呢
首先正常的执行流程上面我们已经分析过了。
下面 我们来看看不正常的流程
new LiveData的时候
public LiveData() {mData NOT_SET;mVersion START_VERSION;
}
mVersion-1
然后执行setValue:
MainThread
protected void setValue(T value) {assertMainThread(setValue);mVersion;mData value;dispatchingValue(null);
}
mVersion 0
这时不会走到
private void considerNotify(ObserverWrapper observer) {if (!observer.mActive) {return;}// Check latest state b4 dispatch. Maybe it changed state but we didnt 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 weve 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
void dispatchingValue(Nullable ObserverWrapper initiator) {if (mDispatchingValue) {mDispatchInvalidated true;return;}mDispatchingValue true;do {mDispatchInvalidated false;if (initiator ! null) {considerNotify(initiator);initiator null;} else {for (IteratorMap.EntryObserver? super T, ObserverWrapper iterator mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {considerNotify(iterator.next().getValue());if (mDispatchInvalidated) {break;}}}} while (mDispatchInvalidated);mDispatchingValue false;
}
所以此时observer.mLastVersion -1
但是因为是一个while循环所以当绑定observer时然后会走到
private void considerNotify(ObserverWrapper observer) {if (!observer.mActive) {return;}// Check latest state b4 dispatch. Maybe it changed state but we didnt 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 weve 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);
}
然后我们就会收到消息。
所以就造成了我们订阅之前的消息也收到了。
五解决方案
public class MyLiveDataT extends MutableLiveDataT {private int mVersion 0;//被观察者的版本private int observerVersion 0;//观察者的版本Overridepublic void observe(NonNull LifecycleOwner owner, NonNull Observer? super T observer) {//每次订阅的时候先把版本同步observerVersion mVersion;super.observe(owner, new ObserverT() {Overridepublic void onChanged(T t) {if (mVersion ! observerVersion) {observer.onChanged(t);}}});}MainThreadpublic void setValue(T value) {mVersion;super.setValue(value);}}