目录
- 一、android分层架构
- 二、ViewModel + LiveData
- 2.1 LiveData 特性
- 观察者的回调永远发生在主线程
- 仅持有单个且最新数据
- 自动取消订阅
- 提供「可读可写」和「仅可读」两种方式
- 配合 DataBinding 实现「双向绑定」
- 2.2 LiveData的缺陷
- value 可以是 nullable 的
- 传入正确的 lifecycleOwner
- 粘性事件
- 默认不防抖
- transformation 工作在主线程
- 2.3 LiveData 小结
- 三、Flow
- 3.1 简介
- 3.2 基本概念
- 3.3 StateFlow
- 基本使用
- 3.4 SharedFlow
- SharedFlow基本概念
- 基本使用
- 3.5 冷流转热流
- 3.6 StateFlow与SharedFlow对比
- 四、总结
一、Android分层架构
不管是早期的MVC、MVP,还是最新的MVVM和MVI架构,这些框架一直解决的都是一个数据流的问题。一个良好的数据流框架,每一层的职责是单一的。例如,我们可以在表现层(Presentation Layer)的基础上添加一个领域层(Domain Layer) 来保存业务逻辑,使用数据层(Data Layer)对上层屏蔽数据来源(数据可能来自远程服务,可能是本地数据库)。
在Android中,一个典型的Android分层架构图如下:
其中,我们需要重点看下Presenter 和 ViewModel, Presenter 和 ViewModel向 View 提供数据的机制是不同的。
- Presenter: Presenter通过持有 View 的引用并直接调用操作 View,以此向 View 提供和更新数据。
- ViewModel:ViewModel 通过将可观察的数据暴露给观察者来向 View 提供和更新数据。
目前,官方提供的可观察的数据组件有LiveData、StateFlow和SharedFlow。可能大家对LiveData比较熟悉,配合ViewModel可以很方便的实现数据流的流转。不过,LiveData也有很多常见的缺陷,并且使用场景也比较固定,如果网上出现了KotlinFlow 替代 LiveData的声音。那么 Flow 真的会替代 LiveData吗?Flow 真的适合你的项目吗?看完下面的分析后,你定会有所收获。
二、ViewModel + LiveData
ViewModel的作用是将视图和逻辑进行分离,Activity或者Fragment只负责UI显示部分,网络请求或者数据库操作则有ViewModel负责。ViewModel旨在以注重生命周期的方式存储和管理界面相关的数据,让数据可在发生屏幕旋转等配置更改后继续留存。并且ViewModel不持有View层的实例,通过LiveData与Activity或者Fragment通讯,不需要担心潜在的内存泄漏问题。
而LiveData 则是一种可观察的数据存储器类,与常规的可观察类不同,LiveData 具有生命周期感知能力,它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保LiveData当数据源发生变化的时候,通知它的观察者更新UI界面。同时它只会通知处于Active状态的观察者更新界面,如果某个观察者的状态处于Paused或Destroyed时那么它将不会收到通知,所以不用担心内存泄漏问题。
下面是官方发布的架构组件库的生命周期的说明:
2.1 LiveData 特性
通过前面的介绍可以知道,LiveData 是 Android Jetpack Lifecycle 组件中的内容,具有生命周期感知能力。一句话概括就是:LiveData 是可感知生命周期的,可观察的,数据持有者。
特点如下:
- 观察者的回调永远发生在主线程
- 仅持有单个且最新的数据
- 自动取消订阅
- 提供「可读可写」和「仅可读」两个版本收缩权限
- 配合 DataBinding 实现「双向绑定」
观察者的回调永远发生在主线程
因为LiveData 是被用来更新 UI的,因此 Observer 接口的>public interface Observer<T> { void>protected void postValue(T value) { boolean postTask; synchronized (mDataLock) { postTask = mPendingData =http://www.cppcns.com/ruanjian/android/= NOT_SET; mPendingData = value; } if (!postTask) { return; } ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable); }
一文读懂Android Kotlin的数据流
扫一扫手机访问
