概述
1. 背景
LiveData如同它的名字一样,是一个可观察的数据持有者,和常规的observable不同,LiveData是具有生命周期感知的,这意味着它能够在Activity、Fragment、Service中正确的处理生命周期。
LiveData的数据源一般是ViewModel,也可以是其它可以更新LiveData的组件。当数据更新后,LiveData 就会通知它的所有观察者,比如Activiy。与RxJava的方法不同的是,LiveData并不是通知所有观察者,它 只会通知处于Active状态的观察者,如果一个观察者处于Paused或Destroyed状态,它将不会收到通知。 这对于Activiy和Service特别有用,因为它们可以安全地观察LiveData对象而不用担心内存泄漏的问题。开发者也不需要在onPause或onDestroy方法中解除对LiveData的订阅。还有一点需要注意的是一旦观察者重新恢复Resumed状态,它将会重新收到LiveData的最新数据。
2. LiveData的基本用法
2.1 MutableLiveData使用
LiveData是一个抽象类,它的最简单的实现类为MutableLiveData。
class MainActivity : AppCompatActivity() {
protected fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val mutableLiveData: MutableLiveData<String> = MutableLiveData()
mutableLiveData.observe(this, object : Observer<String?> { //1
fun onChanged(@Nullable s: String) {
Log.d(TAG, "onChanged:$s")
}
})
mutableLiveData.postValue("java transfer kotlin") //2
}
companion object {
private const val TAG = "MainActivity"
}
}
复制代码
注释1处的observe方法有两个参数分别是LifecycleOwner和 Observer<T>
,第一个参数就是MainActivity本身,第二个参数新建了一个Observer<String>
,在onChanged方法中得到回调。注释处的postValue方法会在主线程中更新数据,这样就会得到打印的结果。在大多数情况下,LiveData的observe方法会放在onCreate方法中,如果放在onResume方法中,会出现多次调用的问题。除了MutableLiveData的postValue方法,还可以使用setValue方法,它们之前的区别是,setValue方法必须在主线程使用,如果是在工作线程中更新LiveData,则可以使用postValue方法。
2.2 数据的更新
如果我们想要在LiveData对象分发给观察者之前对其中存储的值进行更改,可以使用Transformations.map()和Transformations.switchMap(),下面通过简单的例子来讲解它们。
2.2.1 Transformations.map()
如果想要在LiveData对象分发给观察者之前对其中存储的值进行更改,可以使用Transformations.map()。
class MainActivity : AppCompatActivity() {
protected fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val mutableLiveData: MutableLiveData<String> = MutableLiveData()
mutableLiveData.observe(this, object : Observer<String?> {
fun onChanged(@Nullable s: String) {
Log.d(TAG, "onChanged1:$s")
}
})
val transformedLiveData: LiveData = Transformations.map(mutableLiveData, object : Function<String?, Any?>() {
fun apply(name: String): Any {
return "$name+Android update"
}
})
transformedLiveData.observe(this, object : Observer {
fun onChanged(@Nullable o: Any) {
Log.d(TAG, "onChanged2:$o")
}
})
mutableLiveData.postValue("Android postValue")
}
companion object {
private const val TAG = "MainActivity"
}
}
复制代码
通过Transformations.map(),在mutableLiveData的基础上又加上了字符串”+Android update”。
2.2.2 Transformations.switchMap()
如果想要手动控制监听其中一个的数据变化,并能根据需要随时切换监听,这时可以使用Transformations.switchMap(),它和Transformations.map()使用方式类似,只不过switchMap()必须返回一个LiveData对象。
class MainActivity : AppCompatActivity() {
var mutableLiveData1: MutableLiveData<String>? = null
var mutableLiveData2: MutableLiveData<String>? = null
var liveDataSwitch: MutableLiveData<Boolean>? = null
protected fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mutableLiveData1 = MutableLiveData()
mutableLiveData2 = MutableLiveData()
liveDataSwitch = MutableLiveData<Boolean>() //1
val transformedLiveData: LiveData = Transformations.switchMap(liveDataSwitch, object : Function<Boolean?,
LiveData<String?>?>() {
fun apply(input: Boolean): LiveData<String>? {
return if (input) {
mutableLiveData1
} else {
mutableLiveData2
}
}
})
transformedLiveData.observe(this, object : Observer<String?> {
fun onChanged(@Nullable s: String) {
Log.d(TAG, "onChanged:$s")
}
})
liveDataSwitch.postValue(false) //2
mutableLiveData1.postValue("Android update 1")
mutableLiveData2.postValue("Android update 2")
}
companion object {
private const val TAG = "MainActivity"
}
}
复制代码
注释1处新建一个MutableLiveData<Boolean>()
来控制切换并赋值给liveDataSwitch,当liveDataSwitch的值为true时返回mutableLiveData1,否则返回mutableLiveData2。注释2处将liveDataSwitch的值更新为faske,这样输出的结果为”Android update 2”,达到了切换监听的目的。
2.3 合并多个LiveData数据源
MediatorLiveData继承自mutableLiveData,它可以将多个LiveData数据源集合起来,可以达到一个组件监听多个LiveData数据变化的目的。
class MainActivity : AppCompatActivity() {
protected fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val mutableLiveData1: MutableLiveData<String> = MutableLiveData()
val mutableLiveData2: MutableLiveData<String> = MutableLiveData()
val liveDataMerger = MediatorLiveData<String>()
liveDataMerger.addSource(mutableLiveData1, object : Observer {
fun onChanged(@Nullable o: Any) {
Log.d(TAG, "onChanged1:$o")
}
})
liveDataMerger.addSource(mutableLiveData2, object : Observer {
fun onChanged(@Nullable o: Any) {
Log.d(TAG, "onChanged2:$o")
}
})
liveDataMerger.observe(this, object : Observer {
fun onChanged(@Nullable o: Any) {
Log.d(TAG, "onChanged:$o")
}
})
mutableLiveData1.postValue("Android update")
}
companion object {
private const val TAG = "MainActivity"
}
}
复制代码
为了更直观的举例,将LiveData和MediatorLiveData放到了同一个Activity中。通过MediatorLiveData的addSource将两个MutableLiveData合并到一起,这样当任何一个MutableLiveData数据发生变化时,MediatorLiveData都可以感知到。
打印的结果为: D/MainActivity: onChanged1:Android update
3. 拓展LiveData对象
如果观察者的生命周期处于STARTED或RESUMED状态,LiveData会将观察者视为处于Active状态 。关于如何扩展LiveData,官网的例子是比较简洁的,如下所示。
class StockLiveData private constructor(symbol: String) : LiveData<BigDecimal?>() {
private val stockManager: StockManager
private val listener: SimplePriceListener = object : SimplePriceListener() {
fun onPriceChanged(price: BigDecimal?) {
setValue(price)
}
}
protected fun onActive() {
stockManager.requestPriceUpdates(listener)
}
protected fun onInactive() {
stockManager.removeUpdates(listener)
}
companion object {
private var sInstance: StockLiveData? = null
@MainThread
operator fun get(symbol: String): StockLiveData? {
if (sInstance == null) {
sInstance = StockLiveData(symbol)
}
return sInstance
}
}
init {
stockManager = StockManager(symbol)
}
}
复制代码
上面的代码是一个观察股票变动的一个例子,对LiveData进行了拓展,实现了LiveData的两个空方法onActive和onInactive。当Active状态的观察者的数量从0变为1时会调用onActive方法,通俗来讲,就是当LiveData对象具有Active状态的观察者时调用onActive方法,应该在onActive方法中开始观察股票价格的更新。当LiveData对象没有任何Active状态的观察者时调用onInactive方法,在这个方法中,断开与StockManager服务的连接。
在Fragment中使用StockLiveData,如下所示。
class MyFragment : Fragment() {
fun onActivityCreated(savedInstanceState: Bundle?) {
StockLiveData.get(symbol).observe(this) { price -> }
}
}
复制代码
更多Android进阶知识,大家扫码进群即可获取~
最后
以上就是安静音响为你收集整理的JetPack之LiveData使用1. 背景2. LiveData的基本用法2.3 合并多个LiveData数据源3. 拓展LiveData对象的全部内容,希望文章能够帮你解决JetPack之LiveData使用1. 背景2. LiveData的基本用法2.3 合并多个LiveData数据源3. 拓展LiveData对象所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复