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使用的更多相关文章

  1. Android lifecycle 使用详解

    版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/gdutxiaoxu/article/det ...

  2. Android lifecycle 实战及使用进阶

    版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/gdutxiaoxu/article/det ...

  3. Android lifecyle 源码解剖 - gdutxiaoxu的博客(微信公众号 stormjun94)

    版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/gdutxiaoxu/article/det ...

  4. 【Android】ViewModel+LiveData:更加直接地控制视图的方式

    目录 LiveData 前言 使用ViewModel+LiveData LiveData 前言   ViewModel通过将UI data保存在ViewModel类实例的内部,从而大大地将MVC中的 ...

  5. Android框架式编程之LiveData

    一.LiveData 介绍 LiveData是 Google 推荐的 Android 架构组件之一,是一个基于观察者模式的数据容器,但与一般的被观察者不同的是,它是有生命周期感知功能,解决了Andro ...

  6. Android Studio 之 ROM【3】,LiveData+ViewModel+AsyncTask+Repository+RecyclerView

    教程地址:https://www.bilibili.com/video/av65180549 源码地址:https://github.com/longway777/Android-2019-Tutor ...

  7. Android Studio 之 ROM【2】, LiveData+ViewModel+AsyncTask+Repository

    改造上一节 ROM[1], 1.利用 LiveData<List<Word>> 与 observe 中的 onChanged 配合,删除掉之前的textView更新函数(upd ...

  8. Android Studio 之 LiveData 的配合使用,底层数据变化,自动通知界面

    Android Studio 之 LiveData 的配合使用,底层数据变化,自动通知界面 viewModelWithLikeData.getLikeNumber().observe(this, ne ...

  9. Android Jetpack组件 - ViewModel,LiveData使用以及原理

    本文涉及的源码版本如下: com.android.support:appcompat-v7:27.1.1 android.arch.lifecycle:extensions:1.1.1 android ...

随机推荐

  1. 微信小程序-自定义下拉刷新

    最近给别个公司做技术支持,要实现微信小程序上拉刷新与下拉加载更多 微信给出的接口不怎么友好,最终想实现效果类似QQ手机版 ,一共3种下拉刷新状态变化,文字+图片+背景颜色 最终实现后的效果(这里提示有 ...

  2. 使用C++版本Mxnett进行预测的注意事项

    现在越来越多的人选择Mxnet作为深度学习框架,相应的中文社区非常活跃,而且后面推出的gluon以及gluoncv非常适合上手和实验,特别是gluoncv中提供了非常多.非常新的预训练model zo ...

  3. Ansible工具原理一

    ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef.func.fabric)的优点,实现了批量系统配置.批量程序部署.批量运行命 ...

  4. python 读取wav 音频文件的两种方式

    python 中,常用的有两种可以读取wav音频格式的方法,如下所示: import scipy from scipy.io import wavfile import soundfile as sf ...

  5. .net core dump分析

    服务器上如果出现cpu内存饱满,找不到原因,那么dump文件分析必不可少. 起初是想在linux下调试.net core 的dump,但是环境一直无法安装 搞了许久没搞出来,其次文章太少了,googl ...

  6. strace命令用法

    -tt 在每行输出的前面,显示毫秒级别的时间 -T 显示每次系统调用所花费的时间 -v 对于某些相关调用,把完整的环境变量,文件stat结构等打出来. -f 跟踪目标进程,以及目标进程创建的所有子进程 ...

  7. JavaScript优化细节(一)

    1.置空Closure(闭包)引起的Memory leak滞留的Object和domain 2.用fragment实现append大量元素 var f= document.createDocument ...

  8. Kubernetes 持续集成 SpringCloud

    写在开始之前,在开始之前我们需要了解几个概念: 1.什么是持续集成? 持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成.每次 ...

  9. sql server 性能调优之 资源等待内存瓶颈的三种等待类型

    一.概述 这篇介绍Stolen内存相关的主要三种等待类型以及对应的waittype编号,CMEMTHREAD(0x00B9),SOS_RESERVEDMEMBLOCKLIST(0x007B),RESO ...

  10. mysql 开发基础系列22 SQL Model

    一.概述 与其它数据库不同,mysql 可以运行不同的sql model 下, sql model 定义了mysql应用支持的sql语法,数据校验等,这样更容易在不同的环境中使用mysql. sql ...