1. 程式人生 > >Jetpack系列:LiveData入門級使用方法

Jetpack系列:LiveData入門級使用方法

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

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

  • 確保UI與資料狀態匹配

  • 不需要擔心記憶體洩漏問題

  • Activity停止後資料變化不會導致Crash

  • 不再需要人工生命週期的處理

  • 始終使用最新的資料

  • 正確應用配置更改

  • 共享資源

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

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

file

本例中,資料變化通知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<activitylivedatabinding>(
            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<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)}" ... />
//LiveDataViewModel
val currentTime = dataSource.getCurrentTime()
//DefaultDataSource
override 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}" ... />
//LiveDataViewModel
val currentWeather: LiveData<string> = liveData {
    emit(LOADING_STRING)
    emitSource(dataSource.fetchWeather())
}
//DefaultDataSource
private 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()}" ...></button>
//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<string> = _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在架構元件中的應用:官方文件連結

遠端資料的更新流程為:

file

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

幫助文件原始碼路徑 小技巧: github 程式碼下載速度慢,可以克隆到碼雲上(gitee.com)再下載。

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

歡迎關注公眾號,留言討論更多技術問題

相關推薦

Jetpack系列LiveData入門使用方法

Android APP開發中,開發者們都想有一個公共的元件,可以實現後臺資料的監聽,同時實時更新到UI進行顯示,從而大大簡化開發過

Go基礎系列Go中的方法

Go方法簡介 Go中的struct結構類似於面向物件中的類。面向物件中,除了成員變數還有方法。 Go中也有方法,它是一種特殊的函式,定義於struct之上(與struct關聯、繫結),被稱為struct的receiver。 它的定義方式大致如下: type mytype struct{} func

Qt實現入門英語學習軟體

這是用Qt實現的一個入門級的英語學習軟體,適用於初學者學習~這是我上學期學完C語言專業課後,自己上慕課網學了些C++便找了個框架來實踐寫的,而且介面的設計沒有用Qt的designer拖動控制元件(也就是圖形化編輯模式),是純程式碼實現控制元件的佈局所以會比較簡陋= =。之所以在MFC和Q

Android自定義控制元件系列詳解onMeasure()方法中如何測量一個控制元件尺寸(一)

轉載請註明出處:http://blog.csdn.net/cyp331203/article/details/45027641 今天的任務就是詳細研究一下protected void onMeasure(int widthMeasureSpec, int he

Oracle Data Pump 工具系列Data Pump 許可權配置相關錯誤及解決辦法彙總

與 Data Pump 許可權相關的錯誤及解決辦法: 示例語句: > expdp scott/tiger DIRECTORY=my_dir DUMPFILE=exp_s.dmp \  LOGFILE=exp_s.log SCHEMAS=scott 錯誤1: UDE-00008: operation ge

CYQ.Data入門到放棄ORM系列開篇自動化框架程式設計思維

前言: 隨著CYQ.Data 開始迴歸免費使用之後,發現使用者的情緒越來越激動,為了保持這持續的激動性,讓我有了開源的念頭。 同時,由於框架經過這5-6年來的不斷演進,以前發的早期教程已經太落後了,包括使用方式,及相關介紹,都容易引人誤解。 為此,我打算重新寫個系列來介紹最新的版本,讓大夥從傳統的ORM

CSS 從入門到放棄系列CSS的選擇器和優先

href css選擇器 數量 blue 比較 開頭 解決 ul li 選中 CSS的選擇器和優先級 CSS的N種選擇器 !important 其實這個玩意不算什麽選擇器,放在這只是為了突出這個選擇器優先級或者說權重的從高到低而已。。 內聯方式(行間樣式) <div

雲星資料---Scala實戰系列(精品版)】Scala入門教程034-Scala實戰原始碼-Scala apply方法02 初始化物件

Scala 呼叫apply() 初始化物件 package scala_learn.demo08_Apply /** * Created by liguohua on 2017/3/1. *

機器學習入門之四機器學習的方法-神經網絡(轉載)

轉載 bsp 圖像 src nbsp 加速 數值 str 我們   轉自 飛鳥各投林   神經網絡      神經網絡(也稱之為人工神經網絡,ANN)算法是80年代機器學習界非常流行的算法,不過在90年代中途衰落。現在,攜著“深度學習”之勢,神

JAVA通信系列Netty入門總結

hand list code end @override ada 群發消息 -s object 一、Netty學習資料 書籍《Netty In Action中文版》 對於Netty的十一個疑問http://news.cnblogs.com/n/205413/ 深入淺出Net

Java入門系列實例講解ArrayList用法

contains www. ech initial 接口 jsp 需要 print create 本文通過實例講解Java中如何使用ArrayList類。 Java.util.ArrayList類是一個動態數組類型,也就是說,ArrayList對象既有數組的特征,也有鏈表

(轉)Android開發書籍推薦入門到精通系列學習路線書籍介紹

成長 程序員 理論 targe base 官方 app als 自己的 Android開發書籍推薦:從入門到精通系列學習路線書籍介紹 轉自:http://blog.csdn.net/findsafety/article/details/52317506 很多時候我們都會

java web 入門 開發 常用頁面調試方法

文件的 數據 生效 str debugger 操作數 ron 速查 現在 這裏介紹一下Java web 入門級開發中常用的代碼調式方法; ( 僅供入門級童靴 參考) ; 工具: chrome 瀏覽器 (版本越高越好); Java web 入門級開發 主要就是兩個方

Oracle-4 - 超級適合初學者的入門筆記plsql,基本語法,記錄類型,循環,遊標,異常處理,存儲過程,存儲函數,觸發器

個人 就會 逗號 n) 循環結構 less 寫上 所有 targe 初學者可以從查詢到現在的pl/sql的內容都可以在我這裏的筆記中找到,希望能幫到大家,視頻資源在 資源, 我自己的全套筆記在 筆記 在pl/sql中可以繼續使用的sql關鍵字有:update delet

linux高編程基礎系列線程間通信

clas ++ lock 種類型 try 所有者 嘗試 .html 基礎 linux高級編程基礎系列:線程間通信 轉載:原文地址http://blog.163.com/jimking_2010/blog/static/1716015352013102510748824/

PhpStorm中如何使用Xdebug工具,入門操作方法

sso nts 日誌文件 允許 deb src sdn 2.3 選擇 2.1準備工作 PHPSTORM版本 : 8.0.3 PHP版本 : 5.5.12 xdebug版本:php_xdebug-2.2.5-5.5-vc11.dll 註 : php版本和xdebug版本

Python爬蟲系列判斷目標網頁編碼的幾種方法

qpi data- tps 分享 運行 ofo html nbsp 來看 在爬取網頁內容時,了解目標網站所用編碼是非常重要的,本文介紹幾種常用的方法,並使用幾個網站進行簡單測試。 代碼運行結果: 從不同國家的幾個網站測試結果來看,utf8使用的較多(對於純英文網站,用什

python面向對象高反射、魔法方法、元類

txt 一個 賦值 選擇 兩種 固定 __init__ 同時存在 高級 自省/反射什麽是反射?自省也稱作反射,這個性質展示了某對象是如何在運行期取得自身信息的。並且在python裏,反射可以使得程序運行時對象擁有增刪改查它本身屬性或行為的一種能力如果Python不支持某種形

大數據入門學習SQL與NOSQL數據庫

修改配置 mongod 分享 耦合 沒有 nosql 數據表 tor RoCE 這幾年的大數據熱潮帶動了一激活了一大批hadoop學習愛好者。有自學hadoop的,有報名培訓班學習的。所有接觸過hadoop的人都知道,單獨搭建hadoop裏每個組建都需要運行環境、修改配置文

SuSE11安裝MySQL5.1.73RPM安裝方式(超簡單入門安裝)

databases ade 環境 bsp run schema input comm evel 註:此安裝過程只有關鍵步驟,僅適合入門學習使用一、 環境準備 64位操作系統,SuSE版本11sp3。(註:kingtry是我的主機名)kingtry:~ # uname