jetpack-liveData 原理解析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jetpack-liveData 原理解析相关的知识,希望对你有一定的参考价值。

参考技术A

liveData是个可观察的数据持有者,和常规的observable不同,liveData具有生命周期感知的,这意味着它能够在activity fragment service中正确的处理生命周期。liveData很少单独使用,更多的是和android jetpack 其他组件配合使用,比如viewmodel。
当数据更新后,liveData就会通知它所以的观察者,和RXJava不同的时候,liveData 并不是通知所有的观察者,它只会通知处于Active状态的观察者。如果一个观察者处于Paused状态或者destoryed状态(lifecycle状态),不会收到通知。
liveData也不会产生内存泄漏问题,开发者不需要在onPause或者onDestory中解除对liveData的订阅,因为liveData在内部结构中,会一直判断当前状态,当处于destoryed时候,就会自动移除订阅。

1.创建liveData实例对象。mutableLiveData继承LiveData(抽象类)

2.订阅(observe)观察者,传入lifecycle对象和Observer接口,Observer是个泛型接口,为了回调数据,只声明了一个onChanged函数。

3.发送数据,postValue 异步子线程发送,setValue 主线程发送

订阅的过程,就是创建观察者,对lifecycle进行订阅,如此就可以感知activity fragment等生命周期

postValue 通过 handle 从子线程切换为主线程,最终还是调用setValue

【源码解析】RecyclerView的工作原理

参考技术A 在平时的开发过程中,当用到滑动布局时,我们用的比较多的是ListView或ScrollView,但对于RecyclerView的使用却比较少,也就是在需要用到水平滑动布局时才会想到RecyclerView。那在有了ListView的情况下,为什么Google还要推出RecyclerView呢?下面我们从源码角度来分析一下该RecyclerView的布局与缓存原理,看看其与ListView有什么区别。

RecyclerView 一般使用方式是在 Layout 中定义布局文件,然后在 Activity 中通过 findViewById 来拿到 RecyclerView 的实例对象,因此我们从 RecyclerView 的构造函数入手进行分析。

构造函数中告诉我们,可以在布局文件中通过 app:layoutManager 来设置 RecyclerView 的 LayoutManager 对象。 LayoutManager 主要负责 RecyclerView 的布局。

拿到 RecyclerView 对象后,如果在构造函数中没有设置 LayoutManager ,可以通过调用 RecyclerView 的 setLayoutManager(RecyclerView.LayoutManager layout) 方法进行设置。

然后 RecyclerView 会调用 setAdapter 方法。

setAdapterInternal 方法主要作用是将传进来的 adapter 保存到 mAdapter 变量。之后调用了 requestLayout 方法。

requestLayout 方法又调用了父类的 requestLayout 方法,最终调用了 View 的 requestLayout 方法。

上面的 mParent 的真正实例为 ViewRootImpl ,也就是说执行了 ViewRootImpl 的 requestLayout 方法。

scheduleTraversals 方法被执行,意味着后续开始执行 RecyclerView 的 onMeasure 、 onLayout 、 onDraw 方法,之后 RecyclerView 中子视图就展示出来了。

这里我们将 onLayout 方法单拎出来进行分析,因为 RecyclerView 之所以能适配多种滚动布局,主要是 onLayout 方法发挥作用。

onLayout 方法接着调用了 dispatchLayout 方法。

dispatchLayout 方法依次调用了 dispatchLayoutStep1 、 dispatchLayoutStep2 、 dispatchLayoutStep3 方法。

我们首先看 dispatchLayoutStep1 方法。

dispatchLayoutStep1 方法中调用了 mLayout 的 onLayoutChildren 方法。上面分析告诉我们, mLayout 就是 LayoutManager ,所以我们转到 LayoutManager 的 onLayoutChildren 方法。

onLayoutChildren 方法是一个空实现,其具体实现在各个子类中。我们拿 LinearLayoutManager 进行分析,看其中 onLayoutChildren 的实现。

onLayoutChildren 方法中的注释已经为我们说明了 RecyclerView 的布局算法, mAnchorInfo 为布局锚点信息,包含了子控件在Y轴上起始绘制偏移量(coordinate), itemView 在 Adapter 中的索引位置(position)和布局方向(mLayoutFromEnd)-表示start、end方向。该方法的功能是:确定布局锚点,并以此为起点向开始和结束方向填充 ItemView ,如下图所示。

在 onLayoutChildren 方法中,调用了 fill 方法,从该方法名可以知道,该方法应该是将子控件加入到 RecyclerView 中的。

fill 方法中循环调用了 layoutChunkResult 方法。

layoutChunk 方法中,layoutState的next方法将从 Recycler 获取的 View 添加到 RecyclerView 中,从而完成了整个 RecyclerView 的布局。

以上就是 RecyclerView 渲染过程的源码分析,接下来我们来分析一下 RecyclerView 的滑动过程。

RecyclerView 本质上就是一个 View ,所以我们从它的 onTouchEvent 方法入手进行分析。

onTouchEvent 方法中主要关注的是 action 为 MotionEvent.ACTION_MOVE 的情况,在滑动过程中调用了 scrollByInternal 方法。

当上下滑动时,垂直方向上的y偏移量是不等于0的,从而执行了 LayoutManager 的 scrollVerticallyBy 方法。我们拿 LinearLayoutManager 的 scrollVerticallyBy 来举例。

当上下滑动时,执行了 scrollBy 方法。

scrollBy 方法中又执行了 fill 方法,该方法的作用是向可填充区域填充 itemView ,我们具体看一下 fill 方法的实现。

fill方法中又调用了layoutChunk方法。

layoutChunk 方法中出现了一个很重要的方法,就是 LayoutManager.LayoutState 的 next 方法,该方法的实现如下。

这里通过Recycler去获取了一个可重复利用的View,若该View不存在则创建一个新View,原理和ListView的Recycler基本无异。下图展示了RecyclerView循环复用View的原理。

本文从源码的角度分析了RecyclerView的布局与滑动过程中View的缓存原理。相对于ListView来说,RecyclerView的布局和View的缓存原理与ListView差不多一致,但是RecyclerView扩展了ListView的特性,不但可以做到垂直滑动,也能做到水平滑动,并且在创建多样式滚动View方面也做得比ListView出色。可以说,RecyclerView就是ListView的一个增强版本。

以上是关于jetpack-liveData 原理解析的主要内容,如果未能解决你的问题,请参考以下文章

Bagging原理解析

Zookeeper原理解析

Kubernetes Service原理解析

WebRTC原理解析

SpringBoot Starter运行原理代码解析

【转载】AlphaGo原理解析