您当前的位置:首页 > 电脑百科 > 程序开发 > 移动端 > Android

android Jetpack LiveData用法你知道吗?

时间:2019-08-01 10:58:55  来源:  作者:

LiveData用法介绍

LiveDataAndroid Jetpack里的一个组件库,它具有感知activity和fragment生命周期的功能,使用观察者模式设置数据并确保数据在activity和fragment正确的生命周期内更新ui,提升App性能,并防止app crash

先来看一个非常简单的例子

class LiveDataActivity : AppCompatActivity() {
 var liveData: MutableLiveData<String>? = null
 var disposable: Disposable? = null
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_livedata)
 liveData = MutableLiveData()
 // 观察数据的变化,只有在界面可见的时候才会回调(即onStart或onResume状态)
 liveData!!.observe(this, Observer {
 tv_text.text = it
 })
 loadData()
 }
 override fun onDestroy() {
 super.onDestroy()
 disposable?.dispose()
 }
 private fun loadData() {
 disposable = Flowable.interval(1, 1, TimeUnit.SECONDS)
 .observeOn(AndroidSchedulers.mainThread())
 .subscribe {
 // 更新数据
 liveData?.value = it.toString()
 }
 }
}

LiveData的用法非常简单,首选new一个LiveData对象,然后通过observe方法添加一个Observer,并实现Observer接口的onChanged方法,最后在数据更新的时候使用livedata的setValue方法更新数据即可;调用setValue方法的时候,如果当前Activity处于onStart或onResume状态,则会调用Observer的onChanged回调,否则先缓存数据,当Activity重新回到onStart或onResume状态时,再调用Observer的onChanged回调(Activity destroy时 会自动remove Observer,所以不需要我们手动remove)

LiveData 几个比较重要的方法介绍

setValue(T value)

  • 必须在 UI Thread 中调用,更新数据,同时当Activity处于onStart或onResume状态时会调用Observer的onChanged回调

postValue(T value)

  • 跟setValue()一样,唯一的区别就是可以 非UI Thread 中调用,然后通过handler post在UI Thread中回调

observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)

  • 这是一个非常常用的方法, 用于添加一个Observer,监听数据的变化; LifecycleOwner 一般是activity 或 fragment对象,使其LiveData可以感知其生命周期,只有在onStart或onResume状态时会调用Observer的onChanged回调, 在destroy时 remove Observer

observeForever(@NonNull Observer<? super T> observer)

  • 跟observe方法差不多,唯一的区别是没办法感知activity 或 fragment生命周期;即只要有数据更新就立马调用Observer的onChanged回调,并且需要手动remove Observer;这个方法对于Transformation(数据转换)非常有用,下面会介绍到

removeObservers(@NonNull final Observer<? super T> observer)

  • 这个方法很简单,就是删除某个observer

onActive()

  • 这是LiveData的一个回调方法,当observer的数量由0变成1的时候,会调用

onInactive()

  • 这是LiveData的一个回调方法,当observer的数量由1变成0的时候,会调用

MutableLiveData 介绍

MutableLiveData 比较简单,一般没什么特殊需求,用MutableLiveData就可以,他的源码实现也非常简单

public class MutableLiveData<T> extends LiveData<T> {
 @Override
 public void postValue(T value) {
 super.postValue(value);
 }
 @Override
 public void setValue(T value) {
 super.setValue(value);
 }
}

只是将LiveData用protected修饰postValue和setValue的方法改成了public

用法就跟上面的demo一样

MediatorLiveData 介绍

MediatorLiveData继承MutableLiveData, 并提供addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged)方法监听LiveData的数据更新,然后做一层处理或直接通知给最外层的Observer

先看一下源码里的example, 只处理前10次数据的变化

LiveData<String> liveData1 = ...;
var liveDataMerger = MediatorLiveData<String>()
liveDataMerger.addSource(liveData1, object: Observer<String> {
 var count = 1
 override fun onChanged(t: String) {
 count++
 // 在这里更新liveDataMerger的数据;因此可以在这里对数据做一些额外的处理之后再更新
 liveDataMerger.value = t
 if (count > 10) {
 liveDataMerger.removeSource(liveData1)
 }
 }
})

同时它还可以监听多个LiveData的变化

val liveData1 = MutableLiveData<String>()
val liveData2 = MutableLiveData<String>()
var liveDataMerger = MediatorLiveData<String>()
liveDataMerger.addSource(liveData1, Observer { liveDataMerger.value = it })
liveDataMerger.addSource(liveData2, Observer { liveDataMerger.value = it })
// 只要liveData1和liveData2数据有更新就会通知Observer更新ui
liveDataMerger.observe(this, Observer {
 tv_text.text = it
})

其实MediatorLiveData最常用的用法是结合Transformation来使用,下面将介绍Transformation的用法

Transformation 转换

Transformation内部原理使用MediatorLiveData实现的

有的时候我们需要对当前data 转换成我们需要的另一种data

比如rxJAVA的map方法

Flowable.range(1, 10)
	.map { "index: $it" }
	.subscribe {
		
	}

再比如 kotlin自带的map扩展方法

val list = listOf(1, 2, 3, 4).map {
 "index: $it"
}

LiveData 也提供了类似的map功能

// 创建LiveData
val userLiveData: LiveData<User> = MutableLiveData<User>()
val userName: LiveData<String> = Transformations.map(userLiveData) {
 user -> "${user.name} ${user.lastName}"
}
//观察数据的更新
userName.observe(this, Observer {
 tv_text.text = it
})
...
// 更新数据
userLiveData.value = User("zhang", "san")

LiveData 也提供了switchMap方法转换数据,它与map唯一的不同是将data转换成一个LiveData<T>,因此在转换过程中可以继续做异步操作请求数据等,他跟rxjava的flatmap方法有点像

// 先使用room数据库定义一个UserDao example
@Dao
abstract class UserDao {
 @Query("select * from tab_user where uid = :uid")
 abstract fun getById(uid: Long): LiveData<User>
}	
...
private fun getUser(id: String): LiveData<User> {
	// 可以使用room数据查询user对象
 // return AppDataBase.getUserDao().getUser(id)
 // 你也可以发网络请求查询user对象
 return object: LiveData<User>() {
 override fun onActive() {
 super.onActive()
 // 模拟网络请求数据
 Flowable.timer(3, TimeUnit.SECONDS)
 .subscribe {
 postValue(User("zhang", "san"))
 }
 }
 }
}
...
val userId: LiveData<String> = MutableLiveData<String>()
val user = Transformations.switchMap(userId) { id -> getUser(id) }
//观察数据的更新
user.observe(this, Observer {
 tv_text.text = "${it.name} ${it.name}"
})
...
// 更新数据
userId.value = "001"

LiveData使用起来比较简单,功能就介绍到这里,建议查看一下官方demo 学习结合其它library的用法



Tags:android   点击:(1253)  评论:(0)
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
今天面试遇到同学说做过内存优化,于是我一般都会问那 Bitmap 的像素内存存在哪?大多数同学都回答在 java heap 里面,就比较尴尬,理论上你做内存优化,如果连图片这个内存大户内存...【详细内容】
2021-12-23  Tags: android  点击:(8)  评论:(0)  加入收藏
Android logcat日志封装logcat痛点在Android开发中使用logcat非常频繁,logcat能帮我们定位问题,但是在日常使用中发现每次使用都需要传递tag,并且会遇到输出频率很高的log,在多...【详细内容】
2021-12-22  Tags: android  点击:(8)  评论:(0)  加入收藏
对项目的基本介绍 1.整个框架主要是给MVVM框架使用的,自己写完interface接口后,通过自定义的注解就能自动生成接口方法 2.用Kotlin的Flow去代替Rxjava,因为我发现RxJava功能很...【详细内容】
2021-12-08  Tags: android  点击:(17)  评论:(0)  加入收藏
前言在Android开发过程中,有些时候会根据需要引用别的项目到当前项目里面,而且以Module形式引用。所以本篇博文就来分享一下怎么以Module形式引用别的项目到当前项目中,方便开...【详细内容】
2021-12-07  Tags: android  点击:(22)  评论:(0)  加入收藏
新型Android恶意木马程序伪装成数十款街机、射击和策略游戏,通过华为应用市场AppGallery进行分发,从而窃取设备信息和用户的手机号码,全球目前至少有930万台Android设备被该恶...【详细内容】
2021-12-01  Tags: android  点击:(24)  评论:(0)  加入收藏
作者:fundroid这篇文章偏阅读一些,大家可以了解下 Android 的一些最新动向。每年9/10月份 Google 都会举行约为期2天的 Android Dev Summit,在活动上 Google 的技术专家们会分...【详细内容】
2021-11-30  Tags: android  点击:(15)  评论:(0)  加入收藏
一、 准备工作1、安装JDK,下载地址(可能需要一个oracle账号,大家百度一下或者自行注册一个就行。尽可能选择8或者11,这两个是长期版本)Java SE | Oracle Technology Network | Or...【详细内容】
2021-11-23  Tags: android  点击:(28)  评论:(0)  加入收藏
如果你是一名忠实的Android玩家,那么可能会知道,今年的Android 12系统在版本规划上与“往届”相比可以说是很有些特殊。具体来说,除了前段时间刚刚推出正式版的Android 12外,谷...【详细内容】
2021-11-10  Tags: android  点击:(24)  评论:(0)  加入收藏
使用Maven Publish Plugin插件。(官方支持)一、在Library的build.gradle中配置plugins { id &#39;com.android.library&#39; id &#39;kotlin-android&#39; id &#39;k...【详细内容】
2021-11-05  Tags: android  点击:(37)  评论:(0)  加入收藏
今年5月,谷歌推出了Android 12,这是原生安卓系统史上最大的设计变化,10月4日,谷歌推出全新的Android12正式版本,并且宣布会在今年晚些时候应用于安卓设备,对比Android11的挤牙膏式...【详细内容】
2021-10-29  Tags: android  点击:(125)  评论:(0)  加入收藏
▌简易百科推荐
今天面试遇到同学说做过内存优化,于是我一般都会问那 Bitmap 的像素内存存在哪?大多数同学都回答在 java heap 里面,就比较尴尬,理论上你做内存优化,如果连图片这个内存大户内存...【详细内容】
2021-12-23  像程序那样思考    Tags:Android开发   点击:(8)  评论:(0)  加入收藏
Android logcat日志封装logcat痛点在Android开发中使用logcat非常频繁,logcat能帮我们定位问题,但是在日常使用中发现每次使用都需要传递tag,并且会遇到输出频率很高的log,在多...【详细内容】
2021-12-22  YuCoding    Tags:Android   点击:(8)  评论:(0)  加入收藏
对项目的基本介绍 1.整个框架主要是给MVVM框架使用的,自己写完interface接口后,通过自定义的注解就能自动生成接口方法 2.用Kotlin的Flow去代替Rxjava,因为我发现RxJava功能很...【详细内容】
2021-12-08  网易Leo    Tags:Android开发   点击:(17)  评论:(0)  加入收藏
前言在Android开发过程中,有些时候会根据需要引用别的项目到当前项目里面,而且以Module形式引用。所以本篇博文就来分享一下怎么以Module形式引用别的项目到当前项目中,方便开...【详细内容】
2021-12-07  网易Leo    Tags:Android开发   点击:(22)  评论:(0)  加入收藏
作者:fundroid这篇文章偏阅读一些,大家可以了解下 Android 的一些最新动向。每年9/10月份 Google 都会举行约为期2天的 Android Dev Summit,在活动上 Google 的技术专家们会分...【详细内容】
2021-11-30  像程序那样思考    Tags:Android开发   点击:(15)  评论:(0)  加入收藏
一、 准备工作1、安装JDK,下载地址(可能需要一个oracle账号,大家百度一下或者自行注册一个就行。尽可能选择8或者11,这两个是长期版本)Java SE | Oracle Technology Network | Or...【详细内容】
2021-11-23  永沧    Tags:Android   点击:(28)  评论:(0)  加入收藏
使用Maven Publish Plugin插件。(官方支持)一、在Library的build.gradle中配置plugins { id &#39;com.android.library&#39; id &#39;kotlin-android&#39; id &#39;k...【详细内容】
2021-11-05  羊城小阳    Tags:Android   点击:(37)  评论:(0)  加入收藏
谷歌离推出Play Store应用程序的新数据隐私部分又近了一步。应用程序开发人员现在可以通过谷歌在Play控制台的新 "数据安全表 "填写相关细节。该公司表示,所需信息将从2022年...【详细内容】
2021-10-20    中关村在线  Tags:安卓   点击:(58)  评论:(0)  加入收藏
架构究竟是什么?如何更好的理解架构?我们知道一个APP通常是由class组成,而这些class之间如何组合,相互之间又如何产生作用,就是影响这个APP的关键点。细分的话我们可以将其分为类...【详细内容】
2021-09-17  像程序那样思考    Tags:Android架构   点击:(52)  评论:(0)  加入收藏
概述当Android应用程序需要访问设备上的敏感资源时,应用程序开发人员会使用权限模型。虽然该模型使用起来非常简单,但开发人员在使用权限时容易出错,从而导致安全漏洞。本文中,...【详细内容】
2021-09-07  SecTr安全团队    Tags:Android开发   点击:(66)  评论:(0)  加入收藏