天天看點

Android Jetpack 資料存儲類——LiveData 庫

作者:願天堂沒有代碼

基礎概念

LiveData 是一種可觀察的資料存儲類,具有生命周期感覺能力;當其資料更新時,會更新通知給處于活躍狀态(STARTED、RESUMED)的觀察者(Observer)

與正常 observable 不同,LiveData 意味着它尊重其他應用程式元件的生命周期,例如活動,片段或服務

LiveData 優勢

LiveData 遵循觀察者模式;當生命周期狀态發生變化時,LiveData 會通知 Observer 對象。您可以整合代碼以在這些 Observer 對象中更新界面;觀察者可以在每次發生更改時更新界面,而不是在每次應用資料發生更改時更新界面

  • 不會發生記憶體洩露
  • 觀察者會綁定到 Lifecycle 對象,并在其關聯的生命周期遭到銷毀後進行自我清理
  • 不會因 Activity 停止而導緻崩潰
  • 如果觀察者的生命周期處于非活躍狀态(如傳回棧中的 Activity),則它不會接收任何 LiveData 事件
  • 不再需要手動處理生命周期
  • 界面元件隻是觀察相關資料,不會停止或恢複觀察
  • LiveData 将自動管理所有這些操作,因為它在觀察時可以感覺相關的生命周期狀态變化
  • 資料始終保持最新狀态
  • 如果生命周期變為非活躍狀态,它會在再次變為活躍狀态時接收最新的資料;例如,曾經在背景的 Activity 會在傳回前台後立即接收最新的資料
  • 适當的配置更改
  • 如果由于配置更改(如裝置旋轉)而重新建立了 Activity 或 Fragment,它會立即接收最新的可用資料
Android Jetpack 資料存儲類——LiveData 庫

共享資源

您可以使用單例模式擴充 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
Android Jetpack 資料存儲類——LiveData 庫

Jetpack 全家桶系列之 LiveData

  • 我們都是 Adapter
  • 理想的資料模型
  • observable
  • lifecycle-aware
  • data holder
  • Transformations
  • LiveData 的錯誤用法
  • 錯誤地使用 var LiveData
  • LiveData 粘性事件
  • 源碼結構
  • LiveData
  • MutableLiveData
  • Observer
  • 源碼分析
Android Jetpack 資料存儲類——LiveData 庫

Jetpack 全家桶目錄

Android Jetpack 資料存儲類——LiveData 庫

由于篇幅有限,資料就不做完全展示了;有需要完整版 Android Jetpack 全家桶進階開發學習筆記的朋友:可以私信 發送 “筆記” 即可 免費擷取

對于程式員來說,要學習的知識内容、技術有太多太多,要想不被環境淘汰就隻有不斷提升自己,從來都是我們去适應環境,而不是環境來适應我們

技術是無止境的,你需要對自己送出的每一行代碼、使用的每一個工具負責,不斷挖掘其底層原理,才能使自己的技術升華到更高的層面

加油!各位 Android 開發者們

繼續閱讀