这是我参与8月更文挑战的第 7 天,活动详情查看:8月更文挑战
分发控制的疑问
在上篇文章中dispatchingValue方法的源码部分里面,除了主体是循环分发数据外,代码段的前后都增加了控制标志,这里面就不贴代码了,可以自行翻看下。
其实这里有一个疑问,分发部分的逻辑都是允许在主线程里面的,为什么这里会有好像是防止并发的控制呢。当然这里的代码不是用来控制并发的,如果是并发的情况这几句控制也不会有什么作用的。这里真正的作用是用来解决重入问题的。
若一个程序或子程序可以“在任意时刻被中断然后操作系统调度执行另外一段代码,这段代码又调用了该子程序不会出错”,则称其为可重入(reentrant或re-entrant)的。
[维基百科] zh.wikipedia.org/wiki/%E5%8F…
[这里学到的可重入] blog.cgsdream.org/2018/10/16/…
因为这里的设计,considerNotify分发内会调用我们自己的回调逻辑,如果我们在回调逻辑内部调用setValue方法给LiveData设置值,这样代码会走到dispatchingValue(null)再次进入这段逻辑,这时候由于mDispatchingValue = true,所以执行mDispatchInvalidated = false然后return,回到上一层这个方法内,这时候就会break,然后再次循环分发依次新数据,保证分发的数据是最新的。这种设计真的是考虑的非常周全了,值得我们学习。
observeForever方法
这个方法是为了在没有LifecycleOwner这样的宿主时使用的,比如我们需要在我们自定义的工具类监听值的变化就可以通过这个方法实现,这个方法在封装回调方法时使用的是AlwaysActiveObserver,其内部的shouldBeActive直接返回true,从而实现了一直可以接受到回调。
子线程更新数据
调用postValue可以在子线程内更新数据,这个方法内就采用了锁来保证在多线程的数据一致,然后通过主线程Handler切换到主线程调用setValue方法。
总结
整体看完一遍可以感觉到整体的代码设计真的是有水平,希望将来我们都能写出这样的代码吧,哈哈。