LiveData 的定义与优势
官方对 LIveData 的定义为:
LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。
从上述定义可以知道:
- LiveData 是一个
可观察 的数据存储类 ; - LiveData 具有
生命周期感知 能力; - LivaData
仅更新 处于活跃生命周期状态( STARTED 或 RESUMED 状态) 的应用组件观察者。
使用 LivaData 的优势
- 确保界面符合数据状态;
- 不会发生内存泄漏;
- 不会因 Activity 的停止而导致崩溃
- 不需要手动处理生命周期
- 数据始终保持最新状态
- 共享资源
- 适当的配置修改
LiveData 的使用
LiveData 基本使用
类型为 LiveData 的对象没有公开的方法给更新其 value,要想更新 LiveData 对象的 value,需要使用 类型为 MutableLiveData 的LiveData 对象,其提供了 setValue(T) 和 postValue(T) 方法,其中如果想在多线程中更新数据只能使用 postValue(T) 方法。
使用步骤主要分三步:
- 创建 LiveData 对象实例(常在 ViewModel 中);
- 创建 Observer 对象(常在 Activity 或者 Fragment 中);
- 使用 observer() 方法将 Observer 对象附加到 LiveData 对象(通常在 Activity 或者 Fragment 中)。
示例如下(由于将可变的 LiveData 暴露给外部是不安全的,因此常见的作法是将其转换为不可变的 LiveData 类型对外部进行提供):
class MyViewModel: ViewModel() {
private val _currentName = MutableLiveData<String>()
val currentName: LiveData<String>
get() = _currentName
init {
_currentName.value = "James Doe"
}
fun setNewName(name: String) {
_currentName.value = name
}
.
.
.
}
将用来用来界面展示的可更新的数据 LiveData 对象创建在 ViewModel 中,而不是创建在对应的 Activity 或 Fragment 中是为了避免是的对应的 Activity 或 Fragment 太过庞大不易后续维护,同时将其实例和 Activity 或 Fragment 分开可以使得 LiveData 对象在配置更改后继续存在。
通常在 Activity 中的onCreate() 或者 Fragment 中的方法中进行 Observer 对象的创建并将其附加到 LiveData 对象,这样做是为了系统不会从 Activity 或 Fragment 的 onResume() 方法进行冗余调用(从生命周期图中可以看出 onCreate() 放执行的次数一般是少于 onResume() 的)。
同时其作用为当 Activity 或 Fragment 在变为活跃状态后就具有可以立即显示的数据,这是由于但应用组件处于 STARTED 状态,就会从正在观察的 LiveData 对象接受最新的数据。观察示例代码如下:
class MainActivity: AppCompatActivity() {
private val viewModel by lazy {
ViewModelProvider(this).get(MyViewModel::calss.java)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
nameTextView.text = currentName.value
viewModel.currentName.observe(this, Observer{ newName: String ->
nameTextView.text = newName
})
button.setOnClickListener {
` val anotherName = "John Doe"
viewModel.setNewName(anotherName)
}
}
}
上述 Observer 中的 newName 实际为 currentName 的 value。设置好后点击按钮就会发现显示的文字已经发生改变,并且在旋转屏幕之后信息也不会发生丢失。
转换 LiveData
对于转换 LiveData 来说,可以使用 Transformations 提供的 map() 与 switchMap() 方法。
-
map() 方法主要应用在给你提供的信息内容较多,但是我们只需要其内容的一部分这种情况。例如有一个 User 类,其属性有姓名,年龄,性别等,但是我们只需要姓名,就可以使用 map()。 val userLiveData: LiveData<User> = UserLiveData()
val userName: LiveData<String> = Transformations.map(userLiveData) {
user -> "${user.name}"
}
-
switchMap() 方法则更多的适用于 ViewModel 中的某个 LiveData 对象是调用其他的方法获取到的,此时可以使用 switchMap() 方法将其转换为一个可观察的 LiveData 对象。 private fun getUser(id: String): LiveData<User> {
...
}
val userId: LiveData<String> = ...
val user = Transformations.switchMap(userId) { id -> getUser(id) }
参考:
LiveData 概览 | Android 开发者 | Android Developers (google.cn)
|