Android开发Jetpack组件LiveData使用讲解
作者:Android技术栈 发布时间:2023-03-21 09:27:49
LiveData概述
LiveData 是一种可观察的数据存储器类: 与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期;这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者
如果观察者(由 Observer 类表示)的生命周期处于 STARTED 或 RESUMED 状态,则 LiveData 会认为该观察者处于活跃状态; LiveData 只会将更新通知给活跃的观察者,为观察 LiveData 对象而注册的非活跃观察者不会收到更改通知
你可以注册与实现 LifecycleOwner 接口的对象配对的观察者; 有了这种关系,当相应的 Lifecycle 对象的状态变为 DESTROYED 时,便可移除此观察者;这对于 Activity 和 Fragment 特别有用,因为它们可以放心地观察 LiveData 对象而不必担心泄露(当 Activity 和 Fragment 的生命周期被销毁时,系统会立即退订它们)
LiveData优势
LiveData 遵循观察者模式; 当生命周期状态发生变化时,LiveData 会通知 Observer 对象。您可以整合代码以在这些 Observer 对象中更新界面。观察者可以在每次发生更改时更新界面,而不是在每次应用数据发生更改时更新界面
不会发生内存泄露
观察者会绑定到 Lifecycle 对象,并在其关联的生命周期遭到销毁后进行自我清理 不会因 Activity 停止而导致崩溃
如果观察者的生命周期处于非活跃状态(如返回栈中的 Activity),则它不会接收任何 LiveData 事件
不再需要手动处理生命周期
界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化
数据始终保持最新状态
如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据
适当的配置更改
如果由于配置更改(如设备旋转)而重新创建了 Activity 或 Fragment,它会立即接收最新的可用数据
共享资源
您可以使用单例模式扩展 LiveData 对象以封装系统服务,以便在应用中共享它们; LiveData 对象连接到系统服务一次,然后需要相应资源的任何观察者只需观察 LiveData 对象
LiveData使用
首先需要引入LiveData库, 因为依赖有传递作用,所以我们依赖下面这一个就可以了
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
LiveData一般情况下要结合ViewModel使用,ViewModel后面会单独篇幅介绍,这里为了演示方便就直接在Activity中使用LiveData了
1 LiveData基本使用
class TestActivity : AppCompatActivity() {
private val TAG by lazy {
TestActivity::class.java.simpleName
}
private val data = MutableLiveData<String>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
data.observe(this, Observer {
Log.i(TAG, "value: ${lifecycle.currentState} + $it ")
})
}
fun onTest(view: View) {
data.postValue("LiveData")
}
//打印信息
TestActivity: value: LiveData
}
LiveData是一个抽象类,MutableLiveData是它的实现类; 首先声明一个MutableLiveData对象,然后调用data.observer(lifecycleOwner, observer), 第一个参数是lifecycleOwner, 在Lifecycle原理篇中详细提到它,它是和生命周期紧密相关的一个类,这里也就是将LiveData组件和生命周期绑定,第二个参数是一个回调,当有数据更新的时候会调用它。然后当点击按钮执行onTest方法的时候,就会更新MutableLiveData数值,导致回调被调用,模拟数据更新
2 Transformations.map()
class TestActivity : AppCompatActivity() {
private val data = MutableLiveData<String>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
data.observe(this, Observer {
Log.d(TAG, "Changed1:$it")
})
val transformedLiveData: LiveData<String> = Transformations.map(data) {
"$it+map"
}
transformedLiveData.observe(this, Observer {
Log.d(TAG, "Changed2:$it")
})
}
fun onTest(view: View) {
data.postValue("LiveData")
}
}
//打印如下
TestActivity:Changed1:LiveData
TestActivity:Changed2:LiveData+map
上述代码使用Transformations.map(data)
将LiveData
中存储的值做了更改,并最终被观察者回调打印
3 Transformations.switchMap()
class TestActivity : AppCompatActivity() {
private lateinit var data1: MutableLiveData<String>
private lateinit var data2: MutableLiveData<String>
private lateinit var switchData: MutableLiveData<Boolean>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
data1 = MutableLiveData()
data2 = MutableLiveData()
switchData = MutableLiveData()
val transformedLiveData: LiveData<String> = Transformations.switchMap(switchData) {
if (it) {
Log.i(TAG, "----------true---data1--")
data1
} else {
Log.i(TAG, "----------false---data2--")
data2
}
}
transformedLiveData.observe(this, Observer {
Log.d(TAG, "onChanged:$it")
})
}
fun onTest(view: View) {
switchData.postValue(true)
data1.postValue("data1")
data2.postValue("data2")
}
}
//打印信息如下
TestActivity: ----------true---data1--
TestActivity: onChanged:data1
Transformations.switchMap()和Transformations.map()很相似,它可以根据需要自由的切换监听,和Transformations.map()的差别在于其方法内部需要返回一个LiveData对象
4 MediatorLiveData.addSource()合并数据
class TestActivity : AppCompatActivity() {
private val data1 = MutableLiveData<String>()
private val data2 = MutableLiveData<String>()
private val mediatorLiveData = MediatorLiveData<String>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mediatorLiveData.addSource(data1) {
Log.d(TAG, "onChanged1:$it")
mediatorLiveData.value = it
}
mediatorLiveData.addSource(data2) {
Log.d(TAG, "onChanged2:$it")
mediatorLiveData.value = it
}
mediatorLiveData.observe(this, Observer {
Log.d(TAG, "onChanged:$it")
})
}
fun onTest(view: View) {
data1.postValue("data1")
}
}
//打印信息如下
TestActivity:onChanged1:data1
TestActivity:onChanged:data1
mediatorLiveData.addSource添加了两个LiveData对象,它内部可以存储多个LiveData数据集,监听多个数据的变化,如当点击执行onTest时候data1数据发生变化时候,会监听到变化的结果,同理如果data2数据源发生变化的时候,也会被监听到
来源:https://blog.csdn.net/m0_70748845/article/details/126089347
猜你喜欢
- 我们知道,当我们按返回或Home键退出应用程序的界面时,应用程序会在后台被挂起。这么设计的好处是,由于应用被系统缓存在内存中,那么在用户打开
- FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写FreeMarker被设计用来生成HTML Web
- 1、Java版package com.lyz.utils.common; import java.io.UnsupportedEncodin
- 接口定义了一系列的行为规范,为类型定义一种Can-Do的功能。例如,实现IEnumerable接口定义了GetEnumerator方法,用于
- 摘要:本文介绍Linq查询基本操作(查询关键字)- from 子句- where 子句- select子句- group 子句- into
- 本文是项目中使用了websocket进行一些数据的推送,对比项目做了一个demo,ws的相关问题不做细数,仅做一下记录。此demo针对ws的
- 一、概述有序数组中常常用到二分查找,能提高查找的速度。今天,我们用顺序查找和二分查找实现数组的增删改查。二、有序数组的优缺点优点:查找速度比
- 一、前言本博文标题和内容参考:基于原生JS实现H5转盘游戏博主将改编成Unity版本。二、效果图三、案例制作1.界面搭建使用了9个图片作为奖
- 本文研究的主要是Java ArrayList扩容问题实例详解的相关内容,具体介绍如下。首先我们需要知道ArrayList里面的实质的其实是一
- 一、BigInteger介绍如果在操作的时候一个整型数据已经超过了整数的最大类型长度 long 的话,则此数据就无法装入,所以,此时要使用
- 下面分几部分介绍C#实现自动售货机接口的方法,代码写的非常详细,不懂的地方有注释可以参考下。MachineJP类:第1部分:串口初始化,串口
- 1)字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 strcat(p, p1)
- 感觉很久不写模拟器代码了,昨天调试的时候碰了点壁,记录下来,避免大家再跟我犯同样的错误。加入Javascript脚本的地方:HtmlElem
- 最近因为用的发送邮件的地方,就查询了资料,总结以下几个方法1、利用新浪邮箱发送2、利用公司邮箱发送3、利用CDO发送,这种方式要引用Inte
- 我们有时候会遇到这样的情况,需要获取某些中文的拼音、中文首字母缩写和中文首字母,下面我将为大家介绍一下如何获取中文拼音的缩写。1、项目建立和
- springboots使用的版本是2.0.1,注意不同版本可能有差异,并不一定通用添加Mybatis的起步依赖:<!--mybatis
- 在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现。对于文件上传,浏览器在上
- Java 8 , Lambda + foreach 语法糖, 写起来非常的 cleanpublic static void main(Str
- 本文实例为大家分享了C#实现飞行棋小游戏的具体代码,供大家参考,具体内容如下逻辑图 以下是掷色子的一个代码,比较有代表性,里面的逻
- 本文为大家分享了Android Studio使用USB真机调试的具体方法,供大家参考,具体内容如下以小米4为例,先将手机通过USB连接电脑,