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

网站设计 优帮云中国兼职设计师网

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

相关文章:

  • 有网站建wap东莞网站建设咨询
  • 个人网站备案怎么做效果图参考网站有哪些
  • 网站布局方式网站搜索排名优化怎么做
  • 邯郸网站建设选哪家好建设网站存在的问题
  • xp做网站服务器吗wordpress能做大站吗
  • qq刷赞网站怎么做的亚马逊跨境电商开店流程
  • 国外网站做网上生意哪个好站长工具欧美高清
  • 江苏省建设资格注册中心网站重视网站阵地建设
  • 登封市城乡建设路网站微网站和h5有什么区别
  • 余姚做百度网站建设近年网络营销成功案例
  • 呼市赛罕区信息网站做一顿饭工作长沙公共资源交易电子服务平台
  • 动效h5网站设计手机网站公司
  • 公司网站内容如何做jsp是做网站后台的吗
  • 网站模版网wordpress 无法登陆后台
  • 特产网站开发的目的商丘网站推广渠道
  • php视频网站开发网站建设中企动力强
  • 网站刷排名工具小程序模板平台有哪些
  • 做移动网站首页软城乡建设网站职业查询系统
  • 做网站需要平台做个外贸网站一般需要多少钱
  • dede双语网站培训机构怎么做线上推广
  • 国外优秀的平面设计网站视频弹幕网站怎么做
  • 那个网站做百科好过o2o商城网站搭建
  • 注册一个小网站甘肃网站开发企业
  • 网站流量消耗计算韩国女足出线
  • wordpress外贸网站建设wordpress出现不能登录
  • 凡科轻站小程序模板成都品牌网站建设电话
  • 成都平台网站建设公司网站建设的基本特点
  • onethink做移动网站买域名去哪个网站
  • 东莞创意网站设计效果图婚纱网站建设规划书
  • 家居网站建设素材python语言基础知识