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. [转]Examining Open vSwitch Traffic Patterns

    In this post, I want to provide some additional insight on how the use of Open vSwitch (OVS) affects ...

  2. 凌华Express CVC D2550 Win7 64-bit无法正常关机的解决办法

    [问题现象]: 在Windows点击shutdown按钮后,显示器一直停在“正在关闭...”的界面上: 此时硬盘已经停止工作了: CPU没有发送S5信号,因此,主板上的电没有被切断: [解决办法]: ...

  3. Javascript高级编程学习笔记(71)—— 模拟事件(1)DOM事件模拟

    事件,指的是网页中某个特定的交互时刻 一般来说事件由浏览器厂商负责提供,一般由用户操作或者其它浏览器功能来触发 但是有一类特殊的事件,那就是由我们开发人员通过JS触发的事件 这些事件和浏览器创建的事件 ...

  4. 第62节:探索Java中的网络编程技术

    前言 感谢! 承蒙关照~ 探索Java中的网络编程技术 网络编程就是io技术和网络技术的结合,网络模型的定义,只要共用网络模型就可以两者连接.网络模型参考. 一座塔有七层,我们需要闯关. 第一层物理层 ...

  5. 使用link标签进行预加载

    概述 html中的link标签一般用来引入css文件.但是也可以通过rel属性来进行预加载.本文记录下相关方法,供以后开发时参考,相信对其他人也有用. 参考资料: mdn 通过rel="pr ...

  6. 前端切图神器-cutterman

    之前我写过一篇关于前端切图的博客:https://www.cnblogs.com/tu-0718/p/9741058.html 但上面的方法在切图量大时依然很费时间,下面向大家推荐这款免费切图神器 c ...

  7. Oracle实战笔记(第一天)

    导读 笔记内容来自韩顺平老师的视频<玩转Oracle实战教程>,可以结合笔记进行观看.第一天视频中还有Oracle的介绍和安装等内容,很容易搜索到,这里就不再进行总结. 目录 1.命令行工 ...

  8. Enum扩展特性,代替中文属性

    由于对英语的天生缺陷,在枚举时一直使用中文,这样就不用看注释就知道枚举意思,今天看到博文 https://www.cnblogs.com/emrys5/p/Enum-rename-htmlhelper ...

  9. Date相关

    处理时间是常见的需求,总结下Date类的相关知识 构建时间对象 Date 对象基于1970年1月1日(世界标准时间)起的毫秒数. 构建对象实例有多种方式: 不传入参数,默认以系统当前时间返回一个时间对 ...

  10. 【ABP框架系列学习】模块系统(4)

    0.引言 ABP提供了构建模块和通过组合模块以创建应用程序的基础设施.一个模块可以依赖于另外一个模块.通常,程序集可以认为是模块.如果创建多个程序集的应用程序,建议为每个程序集创建模块定义. 当前,模 ...