基礎概念
LiveData 是一種可觀察的資料存儲類,具有生命周期感覺能力;當其資料更新時,會更新通知給處于活躍狀态(STARTED、RESUMED)的觀察者(Observer)
與正常 observable 不同,LiveData 意味着它尊重其他應用程式元件的生命周期,例如活動,片段或服務
LiveData 優勢
LiveData 遵循觀察者模式;當生命周期狀态發生變化時,LiveData 會通知 Observer 對象。您可以整合代碼以在這些 Observer 對象中更新界面;觀察者可以在每次發生更改時更新界面,而不是在每次應用資料發生更改時更新界面
- 不會發生記憶體洩露
- 觀察者會綁定到 Lifecycle 對象,并在其關聯的生命周期遭到銷毀後進行自我清理
- 不會因 Activity 停止而導緻崩潰
- 如果觀察者的生命周期處于非活躍狀态(如傳回棧中的 Activity),則它不會接收任何 LiveData 事件
- 不再需要手動處理生命周期
- 界面元件隻是觀察相關資料,不會停止或恢複觀察
- LiveData 将自動管理所有這些操作,因為它在觀察時可以感覺相關的生命周期狀态變化
- 資料始終保持最新狀态
- 如果生命周期變為非活躍狀态,它會在再次變為活躍狀态時接收最新的資料;例如,曾經在背景的 Activity 會在傳回前台後立即接收最新的資料
- 适當的配置更改
- 如果由于配置更改(如裝置旋轉)而重新建立了 Activity 或 Fragment,它會立即接收最新的可用資料
共享資源
您可以使用單例模式擴充 LiveData 對象以封裝系統服務,以便在應用中共享它們LiveData 對象連接配接到系統服務一次,然後需要相應資源的任何觀察者隻需觀察 LiveData 對象
LiveData 使用
首先需要引入 LiveData 庫, 因為依賴有傳遞作用,是以我們依賴下面這一個就可以了
implementation
"androidx.lifecycle:lifecycle-extensions:2.2.0"
LiveData一般情況下要結合 ViewModel 使用,ViewModel 後面會單獨篇幅介紹,這裡為了示範友善就直接在 Activity 中使用 LiveData 了
1 LiveData 基本使用
class TestActivity : AppCompatActivity() {
private val TAG by lazy {
TestActivity::class.java.simpleName
}
private val data = MutableLiveData<String>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
data.observe(this, Observer {
Log.i(TAG, "value: ${lifecycle.currentState} + $it ")
})
}
fun onTest(view: View) {
data.postValue("LiveData")
}
//列印資訊
TestActivity: value: LiveData
}
LiveData 是一個抽象類,MutableLiveData 是它的實作類
首先聲明一個 MutableLiveData 對象,然後調用 data.observer(lifecycleOwner, observer)
第一個參數是 lifecycleOwner,它是和生命周期緊密相關的一個類,這裡也就是将 LiveData 元件和 生命周期 綁定
第二個參數是一個回調,當有資料更新的時候會調用它。然後當點選按鈕執行 onTest 方法的時候,就會更新 MutableLiveData 數值,導緻回調被調用,模拟資料更新
2 Transformations.map()
class TestActivity : AppCompatActivity() {
private val data = MutableLiveData<String>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
data.observe(this, Observer {
Log.d(TAG, "Changed1:$it")
})
val transformedLiveData: LiveData<String> = Transformations.map(data) {
"$it+map"
}
transformedLiveData.observe(this, Observer {
Log.d(TAG, "Changed2:$it")
})
}
fun onTest(view: View) {
data.postValue("LiveData")
}
}
//列印如下
TestActivity:Changed1:LiveData
TestActivity:Changed2:LiveData+map
- 上述代碼使用Transformations.map(data)将LiveData中存儲的值做了更改,并最終被觀察者回調列印
3 Transformations.switchMap()
class TestActivity : AppCompatActivity() {
private lateinit var data1: MutableLiveData<String>
private lateinit var data2: MutableLiveData<String>
private lateinit var switchData: MutableLiveData<Boolean>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
data1 = MutableLiveData()
data2 = MutableLiveData()
switchData = MutableLiveData()
val transformedLiveData: LiveData<String> = Transformations.switchMap(switchData) {
if (it) {
Log.i(TAG, "----------true---data1--")
data1
} else {
Log.i(TAG, "----------false---data2--")
data2
}
}
transformedLiveData.observe(this, Observer {
Log.d(TAG, "onChanged:$it")
})
}
fun onTest(view: View) {
switchData.postValue(true)
data1.postValue("data1")
data2.postValue("data2")
}
//列印資訊如下
TestActivity: ----------true---data1--
TestActivity: onChanged:data1
}
Transformations.switchMap()和 Transformations.map()很相似,它可以根據需要自由的切換監聽,和 Transformations.map()的差别在于其方法内部需要傳回一個 LiveData 對象
4 MediatorLiveData.addSource()合并資料
class TestActivity : AppCompatActivity() {
private val data1 = MutableLiveData<String>()
private val data2 = MutableLiveData<String>()
private val mediatorLiveData = MediatorLiveData<String>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mediatorLiveData.addSource(data1) {
Log.d(TAG, "onChanged1:$it")
mediatorLiveData.value = it
}
mediatorLiveData.addSource(data2) {
Log.d(TAG, "onChanged2:$it")
mediatorLiveData.value = it
}
mediatorLiveData.observe(this, Observer {
Log.d(TAG, "onChanged:$it")
})
}
fun onTest(view: View) {
data1.postValue("data1")
}
//列印資訊如下
TestActivity:onChanged1:data1
TestActivity:onChanged:data1
}
mediatorLiveData.addSource 添加了兩個 LiveData 對象,它内部可以存儲多個 LiveData 資料集,監聽多個資料的變化,如當點選執行 onTest 時候 data1 資料發生變化時候,會監聽到變化的結果,同理如果 data2 資料源發生變化的時候,也會被監聽到
今天有關 Jetpack 的 LiveData 相關内容就講到這裡了,為了是大家能夠更好的學習 Android Jetpack , 在這裡特别提供一份 Android Jetpack 全家桶進階開發學習筆記, 裡面包含了這些年學習 Android Jetpack 開發所遇到的難題及其解決方案; 有需要這份 Android Jetpack 全家桶進階開發學習筆記 的朋友: 可以私信 發送 “筆記” 即可 免費擷取; 希望大家閱讀過後,能夠 查漏補缺;早日成為進階開發者
資料内容展示如下:
Jetpack 全家桶系列之 Navigation
- Navigation 簡介
- Navigation 能做什麼
- Navigation 工作邏輯
- Navigation Graph
- Navigation 的使用技巧
- 同一 graph 中共享 ViewModel
- 嵌套 navigation graph
- Navigation 設計探讨
- fragment replace 你真的了解嗎
- 被重建的 fragment
Jetpack 全家桶系列之 LiveData
- 我們都是 Adapter
- 理想的資料模型
- observable
- lifecycle-aware
- data holder
- Transformations
- LiveData 的錯誤用法
- 錯誤地使用 var LiveData
- LiveData 粘性事件
- 源碼結構
- LiveData
- MutableLiveData
- Observer
- 源碼分析
Jetpack 全家桶目錄
由于篇幅有限,資料就不做完全展示了;有需要完整版 Android Jetpack 全家桶進階開發學習筆記的朋友:可以私信 發送 “筆記” 即可 免費擷取
對于程式員來說,要學習的知識内容、技術有太多太多,要想不被環境淘汰就隻有不斷提升自己,從來都是我們去适應環境,而不是環境來适應我們
技術是無止境的,你需要對自己送出的每一行代碼、使用的每一個工具負責,不斷挖掘其底層原理,才能使自己的技術升華到更高的層面
加油!各位 Android 開發者們