jetpack 协程_Jetpack系列:LiveData入门级使用方法

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对象

name="viewmodel"

type="com.android.example.livedatabuilder.livedataviewmodel" />

...

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 create(modelclass: class): t {

@suppress("unchecked_cast")

return livedataviewmodel(datasource) as t

}

}

注意:此处构造viewmodel采用的datasource为defaultdatasource,后续数据是根据此数据源来进行获取的。

系统时间(long型)显示

系统时间的显示,通过在ui上绑定viewmodel,通过getcurrenttime方法后台更新、提交数据,来通知ui进行显示的更新。

//xml

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秒

}

}

系统时间显示

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

//xml

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()

}

天气显示

天气的显示通过动态改变数据源提供的数据,从而通知ui显示(datasource数据的更新实时通过livedata传递到ui)。

//xml

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])

}

}

远端数据显示

远端数据的请求通过button的点击事件触发,数据获取成功后,通知textview进行数据显示。

//xml

android:id="@+id/cached_value"

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

.../>

android:id="@+id/refresh_button"

android:οnclick="@{() -> 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"//返回此字符串

}

小提示:本例中的viewmodelscope使用的是kotlin coroutines(协程)功能,更多协程使用方法,请查看coroutines在架构组件中的应用:

远端数据的更新流程为:

将上述四个控件分别绑定对应的livedata对象,增加其数据变化,就能够实现前文描述的app动态变化效果了。

小技巧: github 代码下载速度慢,可以克隆到码云上(gitee.com)再下载。

通过这四个控件的livedata与ui的交互使用,你学会如何使用livedata了吗?

欢迎关注公众号,留言讨论更多技术问题。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值