首頁>技術>

Android APP開發中,開發者們都想有一個公共的元件,可以實現後臺資料的監聽,同時實時更新到UI進行顯示,從而大大簡化開發過程。Google針對這一開發需求,提供了Jetpack LiveData元件。下面我們來一起看下LiveData的基本使用方法吧!

首先,先了解下使用LiveData的優點。

確保UI與資料狀態匹配不需要擔心記憶體洩漏問題Activity停止後資料變化不會導致Crash不再需要人工生命週期的處理始終使用最新的資料正確應用配置更改共享資源

LiveData遵循觀察者模式,實現LifeCycle介面,因此可以監聽資料的實時更新,感知應用的生命週期,讓開發者能夠更多的關注業務具體實現。

下面我們來通過一個小Demo來簡單介紹下LiveData的基本使用方法。

本例中,資料變化通知UI的顯示由四個控制元件體現,分別為:系統時間(Long型)、系統時間、天氣、遠端資料。針對這四個控制元件的動態顯示,我們分別來看下其是如何實現的。

框架搭建

APP首先需要搭建使用LiveData的環境:

1. 匯入依賴包

//app build.gradledependencies { ... 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 }//onCreateval binding = DataBindingUtil.setContentView<ActivityLivedataBinding>( this, R.layout.activity_livedata )// Set the LifecycleOwner to be able to observe LiveData objectsbinding.lifecycleOwner = this// Bind ViewModelbinding.viewmodel = viewmodel//LifeDataVMFactoryobject 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)}" .../>//LiveDataViewModelval currentTime = dataSource.getCurrentTime()//DefaultDataSourceoverride 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}" .../>//LiveDataViewModelval currentWeather: LiveData<String> = liveData { emit(LOADING_STRING) emitSource(dataSource.fetchWeather())}//DefaultDataSourceprivate val weatherConditions = listOf("Sunny", "Cloudy", "Rainy", "Stormy", "Snowy")override fun fetchWeather(): LiveData<String> = liveData { var counter = 0 while (true) { counter++ delay(2000)//延時兩秒 //按順序迴圈顯示weatherConditions中的天氣資料資訊 emit(weatherConditions[counter % weatherConditions.size]) }}遠端資料顯示

遠端資料的請求通過Button的點選事件觸發,資料獲取成功後,通知TextView進行資料顯示。

//xml<TextView android:id="@+id/cached_value" android:text="@{viewmodel.cachedValue}" .../><Button android:id="@+id/refresh_button" android:onClick="@{() -> viewmodel.onRefresh()}" .../>//LiveDataViewModelval cachedValue = dataSource.cachedDatafun onRefresh() { // Launch a coroutine that reads from a remote data source and updates cache viewModelScope.launch { dataSource.fetchNewData() }}//DefaultDataSourceprivate val _cachedData = MutableLiveData("This is old data")override val cachedData: LiveData<String> = _cachedDataoverride 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在架構元件中的應用:https://developer.android.google.cn/topic/libraries/architecture/coroutines

遠端資料的更新流程為:

將上述四個控制元件分別繫結對應的LiveData物件,增加其資料變化,就能夠實現前文描述的APP動態變化效果了。

[LiveData官方文件]

https://developer.android.google.cn/topic/libraries/architecture/livedata

[Jetpack架構示例程式碼]

https://github.com/android/architecture-components-samples

小技巧: github 程式碼下載速度慢,可以克隆到碼雲上(gitee.com)再下載。

通過這四個控制元件的LiveData與UI的互動使用,你學會使用LiveData了嗎?

最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 基於golang快速搭建視覺化資料管理後臺的框架