600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > Android Jetpack - LiveData

Android Jetpack - LiveData

时间:2019-04-27 20:05:42

相关推荐

Android Jetpack - LiveData

◾︎简介

LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。

这是官网上的一段话。意思就是 LiveData 的更新能够被 LifecycleOwner 所感知,但是前提是 LifecycleOwner 处于活跃状态。这样就有效的避免了更新 UI 时 Activity 已经不处于活跃而导致的崩溃。

本文代码使用 Kotlin 讲解,若需查看 Java 代码写法,请参考文末 Sample

◾︎添加依赖

LiveData 一般和 ViewModel 一起使用。

def lifecycle_version = "2.3.1"// ViewModelimplementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"// LiveDataimplementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"

◾︎使用

应当避免将 LiveData 直接存储在 Activity / Fragment 中,因为 Activity / Fragment 只负责 UI 显示,而不负责数据存储。

简单的使用 LiveData

在 ViewModel 中定义 LiveData

import androidx.lifecycle.MutableLiveDataimport androidx.lifecycle.ViewModelclass NameViewModel : ViewModel() {val currentName: MutableLiveData<String> by lazy {MutableLiveData<String>()}}

使用 LiveData 的 observe 方法

import androidx.lifecycle.ViewModelProviderviewModel = ViewModelProvider(this)[NameViewModel::class.java]viewModel?.currentName?.observe(this, {name -> textView.text = name })

observe 方法有两个参数

第一个是 LifecycleOwner 对象。这样 LiveData 就会感知 LifecycleOwner 的生命周期,只在 LifecycleOwner 活跃的时候才去调用第二个参数的 onChanged 方法第二个参数是 Observer 对象。Observer 是一个 interface,它的 onChanged 会在 LiveData 更新的时候被调用 更新 LiveData

viewModel?.currentName?.value = "更新 LiveData"

更新 LiveData 有两种方法

setValue。在主线程时使用 setValuepostValue。在子线程时使用 postValue,其实内部就是使用了 Handler 把值 post 到主线程去了。如果在主线程执行之前调用了多次 postValue,只有最后一次有效

LiveData vs MutableLiveData

LiveData 的 setValue 和 postValue 是 protected 的,只能在 ViewModel 内部使用。MutableLiveData 的 setValue 和 postValue 是 public 的,可以在任何地方使用。

自定义 LiveData

自定义一个监听网络状态的 LiveData

import android.content.BroadcastReceiverimport android.content.Contextimport android.content.Intentimport android.content.IntentFilterimport .ConnectivityManagerimport workInfoimport android.util.Logimport androidx.annotation.MainThreadimport androidx.lifecycle.LiveDataclass NetworkLiveData(private val context: Context?) : LiveData<NetworkInfo?>() {private var networkReceiver: NetworkReceiverprivate var intentFilter: IntentFilterinit {networkReceiver = NetworkReceiver()intentFilter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)}companion object {private lateinit var instance: NetworkLiveData@MainThreadfun getInstance(context: Context?): NetworkLiveData {instance = if (::instance.isInitialized) instance else NetworkLiveData(context)return instance}}override fun onActive() {super.onActive()Log.d("tianjf", "onActive")context!!.applicationContext.registerReceiver(networkReceiver, intentFilter)}override fun onInactive() {super.onInactive()Log.d("tianjf", "onInactive")context!!.applicationContext.unregisterReceiver(networkReceiver)}inner class NetworkReceiver : BroadcastReceiver() {override fun onReceive(context: Context?, intent: Intent?) {val connectivityManager =context?.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManagerval networkInfo = connectivityManager?.activeNetworkInfogetInstance(context).value = networkInfo}}}

自定义 LiveData 会覆写 onActive 和 onInactive 方法。它们会监听 LifecyclerOwner 的生命周期。当进入活跃状态(STARTED 或者 RESUMED)时,调用 onActive 方法,当进入非活跃状态时,调用 onInactive 方法。

在 onActivie 中注册广播,在 onInactive 中注销广播。这样代码就非常清晰明了了,网络状态的处理和 Activity/Fragment 分离开了。

转换 LiveData

转换会用到 Translations.map 和 Translations.switchMap

map、switchMap 和 RxJava 中的 map、flatMap 类似

Translations.map

val userLiveData: LiveData<User> = UserLiveData()val userName: LiveData<String> = Transformations.map(userLiveData) {user -> "${user.name} ${user.lastName}"}

当更新 userLiveData 的值时,会自动触发 userName 的 setValue 操作。其实就是对数据做 map 操作,转换为需要的格式。

Translations.switchMap

private fun getUser(id: String): LiveData<User> {...}val userId: LiveData<String> = ...val user = Transformations.switchMap(userId) {id -> getUser(id) }

当设置 userId 的时候,会自动触发 getUser 操作并返回另一个 LiveData

MediatorLiveData

map 和 switchMap 的源码中都使用到了 MediatorLiveData。

从名称可以看出,MediatorLiveData 使用了终结者模式。

MediatorLiveData 可以接管普通的 LiveData,使得当 LiveData 有数据更新的时候,MediatorLiveData 也能够 “收到响应”。

private val originData = MutableLiveData<String>()private val mediatorLiveData = MediatorLiveData<String>()mediatorLiveData.addSource(originData) {Log.i("tianjf", "originData: $it") }

MediatorLiveData 可以添加多个 LiveData

private val originData1 = MutableLiveData<String>()private val originData2 = MutableLiveData<String>()private val mediatorLiveData = MediatorLiveData<String>()mediatorLiveData.addSource(originData1) {mediatorLiveData.value = "originData: $it" }mediatorLiveData.addSource(originData2) {mediatorLiveData.value = "originData: $it" }

observe 和 observeForever

observeForever 和 observe 的区别是,LifecyclerOwner 在非活跃状态下也会调用 Observer 的 onChanged 方法。

为了防止内存泄露,必须手动调用 removeObserver 方法

◾︎Sample

Kotlin 版

Java 版

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。