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( 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
@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
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
emit(LOADING_STRING)
emitSource(dataSource.fetchWeather())
}
//DefaultDataSource
private val weatherConditions = listOf("Sunny", "Cloudy", "Rainy", "Stormy", "Snowy")
override fun fetchWeather(): 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 = https://www.cnblogs.com/danvie/p/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 = https://www.cnblogs.com/danvie/p/MutableLiveData("This is old data")
override val cachedData: LiveData
override suspend fun fetchNewData() {
// Force Main thread
withContext(Dispatchers.Main) {
_cachedData.value = https://www.cnblogs.com/danvie/p/"Fetching new data..."
_cachedData.value = https://www.cnblogs.com/danvie/p/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>

</center>
<br/>
將上述四個控制元件分別系結對應的LiveData物件,增加其資料變化,就能夠實作前文描述的APP動態變化效果了,
<br/>
[幫助檔案](https://developer.android.google.cn/topic/libraries/architecture/livedata)
 
[原始碼路徑](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>

</center>
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/57431.html
標籤:Android
