首页 技术 正文
技术 2022年11月23日
0 收藏 895 点赞 2,472 浏览 4766 个字

Android APP开发中,开发者们都想有一个公共的组件,可以实现后台数据的监听,同时实时更新到UI进行显示,从而大大简化开发过程。Google针对这一开发需求,提供了Jetpack LiveData组件。下面我们来一起看下LiveData的基本使用方法吧!

首先,先了解下使用LiveData的优点。

  • 确保UI与数据状态匹配

  • 不需要担心内存泄漏问题

  • Activity停止后数据变化不会导致Crash

  • 不再需要人工生命周期的处理

  • 始终使用最新的数据

  • 正确应用配置更改

  • 共享资源

LiveData遵循观察者模式,实现LifeCycle接口,因此可以监听数据的实时更新,感知应用的生命周期,让开发者能够更多的关注业务具体实现。

下面我们来通过一个小Demo来简单介绍下LiveData的基本使用方法。

![file](https://img.zhankr.net/yv450vy5eea3348.gif)

本例中,数据变化通知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(
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 {

@Suppress("UNCHECKED_CAST")

return LiveDataViewModel(dataSource) as T

}

}

<br/>
### 注意:此处构造ViewModel采用的dataSource为DefaultDataSource,后续数据是根据此数据源来进行获取的。
<br/>
# 系统时间(Long型)显示
<br/>
系统时间的显示,通过在UI上绑定ViewModel,通过getCurrentTime方法后台更新、提交数据,来通知UI进行显示的更新。
<br/>

//xml

<TextView

android:id="@+id/time"

android:text="@{Long.toString(viewmodel.currentTime)}"

…/>

//LiveDataViewModel

val currentTime = dataSource.getCurrentTime()

//DefaultDataSource

override fun getCurrentTime(): LiveData =

liveData {

while (true) {

emit(System.currentTimeMillis())//通知当前系统时间

delay(1000)//延时1秒

}

}

<br/>
# 系统时间显示
<br/>
系统时间的显示是根据系统获取的Long型变量变化映射得到的,Long值发生变化时,实时更新系统时间显示。
<br/>

//xml

<TextView

android:id="@+id/time_transformed"

android:text="@{viewmodel.currentTimeTransformed}"

…/>

//LiveDataViewModel 此处有两种方式实现

//1. currentTime变更后实时通知UI更新

val currentTimeTransformed : LiveData = 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()

}

<br/>
# 天气显示
<br/>
天气的显示通过动态改变数据源提供的数据,从而通知UI显示(DataSource数据的更新实时通过LiveData传递到UI)。
<br/>

//xml

<TextView

android:id="@+id/current_weather"

android:text="@{viewmodel.currentWeather}"

…/>

//LiveDataViewModel

val currentWeather: LiveData = liveData {

emit(LOADING_STRING)

emitSource(dataSource.fetchWeather())

}

//DefaultDataSource

private val weatherConditions = listOf("Sunny", "Cloudy", "Rainy", "Stormy", "Snowy")

override fun fetchWeather(): LiveData = liveData {

var counter = 0

while (true) {

counter++

delay(2000)//延时两秒

//按顺序循环显示weatherConditions中的天气数据信息

emit(weatherConditions[counter % weatherConditions.size])

}

}

<br/>
# 远端数据显示
<br/>
远端数据的请求通过Button的点击事件触发,数据获取成功后,通知TextView进行数据显示。
<br/>

//xml

<TextView

android:id="@+id/cached_value"

android:text="@{viewmodel.cachedValue}"

…/>

<Button

android:id="@+id/refresh_button"

android:onClick="@{() -> viewmodel.onRefresh()}"

…/>

//LiveDataViewModel

val cachedValue = dataSource.cachedData

fun onRefresh() {

// Launch a coroutine that reads from a remote data source and updates cache

viewModelScope.launch {

dataSource.fetchNewData()

}

}

//DefaultDataSource

private val _cachedData = MutableLiveData("This is old data")

override val cachedData: LiveData = _cachedData

override suspend fun fetchNewData() {

// Force Main thread

withContext(Dispatchers.Main) {

_cachedData.value = "Fetching new data…"

_cachedData.value = simulateNetworkDataFetch()

}

}

private var counter = 0

// Using ioDispatcher because the function simulates a long and expensive operation.

private suspend fun simulateNetworkDataFetch(): String = withContext(ioDispatcher) {

delay(3000)//延时3秒

counter++

"New data from request #$counter"//返回此字符串

}

<br/>
##### 小提示:本例中的viewModelScope使用的是Kotlin Coroutines(协程)功能,更多协程使用方法,请查看Coroutines在架构组件中的应用:[官方文档链接](https://developer.android.google.cn/topic/libraries/architecture/coroutines)[]()
<br/>
远端数据的更新流程为:<br/><br/>
<center>
![file](https://img.zhankr.net/4c0oxu0xsu13349.jpg)
</center>
<br/>
将上述四个控件分别绑定对应的LiveData对象,增加其数据变化,就能够实现前文描述的APP动态变化效果了。<br/>
[帮助文档](https://developer.android.google.cn/topic/libraries/architecture/livedata)
&ensp;
[源码路径](https://github.com/android/architecture-components-samples)<br/><br/>
小技巧: github 代码下载速度慢,可以克隆到码云上(gitee.com)再下载。
<br/><br/>
通过这四个控件的LiveData与UI的交互使用,你学会如何使用LiveData了吗?<br/><br/>
<center><font color='green'>欢迎关注公众号,留言讨论更多技术问题。</center>
<center>
![file](https://img.zhankr.net/zdcswzpctq13350.jpg)
</center>
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,994
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,507
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,350
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,135
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,768
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,845