Android LiveData使用
LiveData是一个可观察的数据持有者类。 与常规observable不同,LiveData是生命周期感知的,当生命周期处于STARTED或RESUMED状态,则LiveData会将其视为活动状态,这意味着它尊重其他应用程序组件的生命周期,例如Activity,Fragment或Service。
LiveData具有以下优点:
- UI和数据保持一致:遵循观察者模式,生命周期状态更改时,LiveData会通知Observer对象
- 避免内存泄漏:观察者绑定到Lifecycle对象,并在其相关生命周期被破坏后自行清理
- 不会因stop而崩溃:处于非活动状态,不会接收到LiveData事件,如Activity变为不可见
- 自动感知生命周期:LiveData自动管理在观察时意识到相关的生命周期状态变化。
- 数据始终保持最新:生命周期变为非活动状态再次变为活动状态时接收最新数据。 例如,Activity不可见变为可见时立即接收最新数据
- 解决Configuration changes问题:当屏幕旋转或者回收时,重新创建Activity或Fragment,可以即时收到数据变更
- 共享资源:使用单例扩展LiveData,就可在app中共享它
- gradle配置
def lifecycle_version = "2.0.0"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
- 创建LiveData对象
class TestViewModel : ViewModel() {
private lateinit var userName: MutableLiveData<String>
fun getUserName(): MutableLiveData<String> {
if (!::userName.isInitialized) {
userName = MutableLiveData()
loadUsers()
}
return userName
}
private fun loadUsers() {
userName.value = "test"
}
}
- 观察和变更LiveData对象
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var model = ViewModelProviders.of(this).get(TestViewModel::class.java)
model.getUserName().observe(this, Observer {
txt_test.text = it
})// 观察
btn_test.setOnClickListener {
model.getUserName().value = "test 2"
}// 变更
}
}
在变更数据的使用有两种方式可用,一个是setValue,另外一个是postValue,区别是setValue只能在主线程处理,postValue可以在子线程处理。
- LiveData结合Databinding使用
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
var model = ViewModelProviders.of(this).get(TestViewModel::class.java)
binding.let {
it.data = model
it.setLifecycleOwner(this)
}
btn_test.setOnClickListener {
model.getUserName().value = "test 2"
}
}
}
binding对象需要调用setLifecycleOwner(LifecycleOwner lifecycleOwner)设置lifecycleOwner对象。
- 扩展LiveData
通常LiveData只关心观察者的STARTED或RESUMED状态,下面代码片段扩展了LiveData
class StockLiveData(symbol: String) : LiveData<BigDecimal>() {
private var mStockManager: StockManager? = null
private val mListener = object : SimplePriceListener() {
fun onPriceChanged(price: BigDecimal) {
value = price
}
}
init {
mStockManager = StockManager(symbol)
}
override fun onActive() {
mStockManager.requestPriceUpdates(mListener)
}
override fun onInactive() {
mStockManager.removeUpdates(mListener)
}
}
实现包括以下重要方法:
- 当 LiveData 对象具有活跃观察者时,会调用 onActive() 方法。这意味着,您需要从此方法开始观察数据更新。
- 当 LiveData 对象没有任何活跃观察者时,会调用 onInactive() 方法。由于没有观察者在监听,因此没有理由与 StockManager 服务保持连接。
- setValue(T) 方法将更新 LiveData 实例的值,并将更改通知给任何活跃观察者。
- 使用扩展LiveData
class TestFragment : Fragment() {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val stockLiveData = StockLiveData("")
stockLiveData.observe(this, Observer {
// update UI
})
}
}
observe() 方法将传递 Fragment(它是 LifecycleOwner 的实例)作为第一个参数。这样做表示此观察者绑定到与所有者关联的 Lifecycle 对象,这意味着:
- 如果 Lifecycle 对象未处于活跃状态,那么即使值发生更改,也不会调用观察者。
- 销毁 Lifecycle 对象后,会自动移除观察者
当然可以在多个 Activity、Fragment 和 Service 之间共享它们,只需要把 StockLiveData类实现为单例。
- 转换 LiveData
LiveData 对象分派给观察者之前对存储在其中的值进行更改,或者您可能需要根据另一个实例的值返回不同的 LiveData 实例。其提供了以下方法进行转换
- Transformations.map()
LiveData<User> userLiveData = ...;
LiveData<String> userName = Transformations.map(userLiveData, user -> {
user.name + " " + user.lastName
});
- Transformations.switchMap()
LiveData<String> userId = ...;
LiveData<User> user = Transformations.switchMap(userId, id -> getUser(id) );
要实现您自己的转换,可以使用 MediatorLiveData 类,该类可以监听其他 LiveData 对象并处理它们发出的事件,其可以正确地将其状态传播到源 LiveData 对象。
Android LiveData使用的更多相关文章
- Android lifecycle 使用详解
版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/gdutxiaoxu/article/det ...
- Android lifecycle 实战及使用进阶
版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/gdutxiaoxu/article/det ...
- Android lifecyle 源码解剖 - gdutxiaoxu的博客(微信公众号 stormjun94)
版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/gdutxiaoxu/article/det ...
- 【Android】ViewModel+LiveData:更加直接地控制视图的方式
目录 LiveData 前言 使用ViewModel+LiveData LiveData 前言 ViewModel通过将UI data保存在ViewModel类实例的内部,从而大大地将MVC中的 ...
- Android框架式编程之LiveData
一.LiveData 介绍 LiveData是 Google 推荐的 Android 架构组件之一,是一个基于观察者模式的数据容器,但与一般的被观察者不同的是,它是有生命周期感知功能,解决了Andro ...
- Android Studio 之 ROM【3】,LiveData+ViewModel+AsyncTask+Repository+RecyclerView
教程地址:https://www.bilibili.com/video/av65180549 源码地址:https://github.com/longway777/Android-2019-Tutor ...
- Android Studio 之 ROM【2】, LiveData+ViewModel+AsyncTask+Repository
改造上一节 ROM[1], 1.利用 LiveData<List<Word>> 与 observe 中的 onChanged 配合,删除掉之前的textView更新函数(upd ...
- Android Studio 之 LiveData 的配合使用,底层数据变化,自动通知界面
Android Studio 之 LiveData 的配合使用,底层数据变化,自动通知界面 viewModelWithLikeData.getLikeNumber().observe(this, ne ...
- Android Jetpack组件 - ViewModel,LiveData使用以及原理
本文涉及的源码版本如下: com.android.support:appcompat-v7:27.1.1 android.arch.lifecycle:extensions:1.1.1 android ...
随机推荐
- Openvswtich 学习笔记
场景: 创建一个Virtual Switch,支持VLAN,支持MAC-Learning 包含下面四个Port: P1, truck port P2, VLAN 20 P3, P4 VLAN 30 包 ...
- Javascript高级编程学习笔记(71)—— 模拟事件(1)DOM事件模拟
事件,指的是网页中某个特定的交互时刻 一般来说事件由浏览器厂商负责提供,一般由用户操作或者其它浏览器功能来触发 但是有一类特殊的事件,那就是由我们开发人员通过JS触发的事件 这些事件和浏览器创建的事件 ...
- 微博第三方登录使用social_django实现显示登陆的用户名
首先修改social_soce源码,将用户信息添加进cookie 将其修改为: response = backend.strategy.redirect(url) payload = jwt ...
- 浅谈final关键字的用法
1.final变量: 常和static一起使用,修饰成员变量或者本地变量.修饰后为常量,不可以再次初始化(再次引用),例如public static final String SUCCESS= &qu ...
- 单元测试mock当前时间
在实际项目中很多地方用到DateTime.Now,这个时间是时时变化的.如果要进行单元测试对比预期结果时,这个时间无法预测,可以添加如下两个时间类 namespace Common.Helper { ...
- Python中变量的命名
变量的命名 目标 标识符和关键字 变量的命名规则 0.1 标识符和关键字 1.1 标识符 标示符就是程序员定义的 变量名.函数名 名字 需要有 见名知义 的效果,见下图: 标示符可以由 字母.下划线 ...
- 玩转Python图片处理 (OpenCV-Python )
OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows.Android和Mac OS操作系统上.它轻量级而且高效——由一系列 C 函数和少量 C++ 类 ...
- 【emotion】目标初定
现在的我漂浮不定,我的心是凌乱的,虽然在我面前的路有无数条,但是我却不知道哪一条路是属于我的.对于java,我掌握的东西可能并不是系统的,想想也知道,自学一年,能形成什么样子的体系呢?然而在日常的工作 ...
- Mybatis 使用备忘录
自动生成Mapper java -jar mybatis-generator-core-1.3.2.jar -configfile generatorConfig.xml -overwrite Myb ...
- 浅谈模块系统与 ABP 框架初始化
在 ABP 框架当中所有库以及项目都是以模块的形式存在,所有模块都是继承自AbpModule 这个抽象基类,每个模块都拥有四个生命周期.分别是: PreInitialze(); Initialize( ...