Android APP开发中,开发者们都想有一个公共的组件,可以实现后台数据的监听,同时实时更新到UI进行显示,从而大大简化开发过程。Google针对这一开发需求,提供了Jetpack LiveData组件。下面我们来一起看下LiveData的基本使用方法吧!
首先,先了解下使用LiveData的优点。
确保UI与数据状态匹配
不需要担心内存泄漏问题
Activity停止后数据变化不会导致Crash
不再需要人工生命周期的处理
始终使用最新的数据
正确应用配置更改
共享资源
LiveData遵循观察者模式,实现LifeCycle接口,因此可以监听数据的实时更新,感知应用的生命周期,让开发者能够更多的关注业务具体实现。
下面我们来通过一个小Demo来简单介绍下LiveData的基本使用方法。
本例中,数据变化通知UI的显示由四个控件体现,分别为:系统时间(Long型)、系统时间、天气、远端数据。针对这四个控件的动态显示,我们分别来看下其是如何实现的。
框架搭建
APP首先需要搭建使用LiveData的环境:
1. 导入依赖包
//app build.gradle
dependencies {
...
implementation deps.lifecycle.viewmodel_ktx
implementation deps.lifecycle.livedata_ktx
...
}
2. 创建ViewModel类(用于LiveData数据的封装,和UI交互)
class LiveDataViewModel(
private val dataSource: DataSource
) : ViewModel() {...}
3. 布局文件中引用ViewModel对象
<layout>
<data>
<variable
name="viewmodel"
type="com.android.example.livedatabuilder.LiveDataViewModel" />
</data>
...
</layout>
4. Activity绑定ViewModel
//MainActivity
//成员变量
private val viewmodel: LiveDataViewModel by viewModels { LiveDataVMFactory }
//onCreate
val binding = DataBindingUtil.setContentView<ActivityLivedataBinding>(
this, R.layout.activity_livedata
)
// Set the LifecycleOwner to be able to observe LiveData objects
binding.lifecycleOwner = this
// Bind ViewModel
binding.viewmodel = viewmodel
//LifeDataVMFactory
object LiveDataVMFactory : ViewModelProvider.Factory {
private val dataSource = DefaultDataSource(Dispatchers.IO)
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
@Suppress("UNCHECKED_CAST")
return LiveDataViewModel(dataSource) as T
}
}
注意:此处构造ViewModel采用的dataSource为DefaultDataSource,后续数据是根据此数据源来进行获取的。
系统时间(Long型)显示
系统时间的显示,通过在UI上绑定ViewModel,通过getCurrentTime方法后台更新、提交数据,来通知UI进行显示的更新。
//xml
<TextView
android:id="@+id/time"
android:text="@{Long.toString(viewmodel.currentTime)}"
.../>
//LiveDataViewModel
val currentTime = dataSource.getCurrentTime()
//DefaultDataSource
override fun getCurrentTime(): LiveData<Long> =
liveData {
while (true) {
emit(System.currentTimeMillis())//通知当前系统时间
delay(1000)//延时1秒
}
}
系统时间显示
系统时间的显示是根据系统获取的Long型变量变化映射得到的,Long值发生变化时,实时更新系统时间显示。
//xml
<TextView
android:id="@+id/time_transformed"
android:text="@{viewmodel.currentTimeTransformed}"
.../>
//LiveDataViewModel 此处有两种方式实现
//1. currentTime变更后实时通知UI更新
val currentTimeTransformed : LiveData<String> = Transformations.map(currentTime) {
Date(it).toString()
}
//2. 延时500ms后通知
val currentTimeTransformed = currentTime.switchMap {
// timeStampToTime is a suspend function so we need to call it from a coroutine.
liveData { emit(timeStampToTime(it)) }
}
private suspend fun timeStampToTime(timestamp: Long): String {
delay(500) // Simulate long operation
val date = Date(timestamp)
return date.toString()
}
天气显示
天气的显示通过动态改变数据源提供的数据,从而通知UI显示(DataSource数据的更新实时通过LiveData传递到UI)。
//xml
<TextView
android:id="@+id/current_weather"
android:text="@{viewmodel.currentWeather}"
.../>
//LiveDataViewModel
val currentWeather: LiveData<String> = liveData {
emit(LOADING_S