当前位置: 首页 > news >正文

德宏傣族景颇族自治州网站建设_网站建设公司_全栈开发者_seo优化

网站设计 优帮云,中国兼职设计师网,规模以上工业企业总产值,武义县网站制作时人不识凌云木#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);}}
http://www.lebaoying.cn/news/75387.html

相关文章:

  • 网站开发公司哪家好汉中微信网站建设推广
  • 大型医院设计网站建设企业解决方案和应对措施
  • 网站开发价格表深圳网页制作服务
  • 健康网站建设与管理昆明网站建设_云南网站建设
  • 北京网站建设公司怎么排版怎样申请微信小程序卖货
  • 曲周网站建设程序员培训机构课程
  • 沧州网站设计公司价格wordpress商业主体
  • 韩国电信 网站wordpress本地网站怎么搬到服务器
  • 金华网站建设哪个公司好点wordpress怎样添加版权名
  • 重庆选科网站可以在视频网站上做新闻节目吗
  • 海洋网络专业网站建设宿迁网站优化
  • 计算机网络技术网站建设方向c 网站开发
  • 成都青羊区网站建设多城市地方门户网站系统
  • 网站域名怎么起广州网站建设 易企建站
  • 欣赏艺术类的网站做抛物线的网站
  • python编程网站wordpress建站和使用
  • 沈阳企业网站排名优化微信小程 wordpress
  • 淮安汽车集团网站建设wordpress微网站模板
  • php自己做网站wordpress 自动收录
  • 设计网站官网有哪些专业人士怎样建网站
  • 2018新网站做外链怎么免费做网站教程
  • 网站建设技术支持英文温岭建设公司网站
  • 贵阳酒店网站建设响应式网站技术
  • 自建网站需要哪些技术邯郸手机建站价格
  • 本地服务网站开发企业网站案例
  • 专门做团购的网站有哪些交互设计专业世界大学排名
  • 学做川菜的网站h5自适应企业网站源码
  • 怎么才能免费建网站企业管理咨询公司简介
  • 图书翻页的动画 做网站启动用服务器搭建网站域名配置
  • 做脚本的网站网站改版301是什么