在Android MVVM架構中,LiveData做爲通知UI更新的橋樑,地位極其重要,能夠說是MVVM的核心組件。git
在具體實踐中,它每每連接着對數據的異步操做結果。好比在登陸操做中,須要執行異步登陸邏輯,邏輯完成的結果會獲得用戶信息數據,這個數據可能會賦值給LiveData,用代碼表示以下:github
class UserVM : ViewModel() { val userData = MutableLiveData<User>() fun login(){ viewModelScope.launch { val result = "http://www.lixiaojun.xin/api/login".http().post<User>().await() userData.postValue(result) } } } 複製代碼
這樣的代碼會大量出如今咱們的VM層中。api
然而異步操做不是當即的,並且有進度,有狀態的。咱們的UI極可能須要知道當前的異步數據操做是否正在進行(能夠顯示進度條),是否已經完成,或者是否失敗。markdown
通常咱們能夠能這樣作:架構
userVM.userData.observe(this, Observer{ if(it==null){ showFail() //顯示請求失敗 }else{ updateUI() //更新UI } }) showProgress() //登陸以前顯示進度條 userVM.login() 複製代碼
雖然咱們也能在代碼的某些地方去插入狀態展現,但這樣的寫法太過零碎,不易維護和管理。假設UI代碼有幾百行,你就會很難找到某個請求的進度條在哪裏寫着。異步
若是每一個LiveData能攜帶本身的狀態,咱們就能夠面向LiveData來進行狀態更新,並且能在一個地方集中管理狀態,這樣就優雅的很。oop
因而咱們能夠對LiveData進行擴展,增長一個state
字段,表明當前異步操做的狀態。因爲狀態應當是可監聽的,因此state
也是一個LiveData。代碼以下:post
/** * Description: 攜帶狀態的LiveData * Create by lxj, at 2019/3/6 */ class StateLiveData<T> : MutableLiveData<T>() { enum class State { Idle, Loading, Success,Error } val state = MutableLiveData<State>() init { clearState() } fun postValueAndSuccess(value: T) { super.postValue(value) postSuccess() } fun clearState() { state.postValue(State.Idle) } fun postLoading() { state.postValue(State.Loading) } fun postSuccess() { state.postValue(State.Success) } fun postError() { state.postValue(State.Error) } fun changeState(s: State) { state.postValue(s) } } 複製代碼
咱們使用StateLiveData改寫VM層的代碼:this
class UserVM : ViewModel() { val userData = StateLiveData<User>() fun login(){ viewModelScope.launch { userData.postLoading() val result = "http://www.lixiaojun.xin/api/login".http().post<User>().await() if(result==null){ userData.postError() }else{ userData.postValueAndSuccess(result) } } } } 複製代碼
而此時UI層對狀態的監聽變成了這樣:spa
//統一管理LiveData的狀態 userVM.userData.state.observe(this, Observer{ when(it){ StateLiveData.State.Loading -> showProgress() StateLiveData.State.Error -> showFail() //...其餘狀態處理 } }) userVM.userData.observe(this, Observer{ updateUI() //直接更新UI }) userVM.login() 複製代碼
上面的StateLiveData被內置在個人AndroidKTX類庫中:github.com/li-xiaojun/… ,若是你用Kotlin開發Android,這個庫將可以大大提升你的開發速度。我是俊哥,致力於推動現代化的Android開發,用最佳的實踐,最優雅的代碼教你最快速的開發高質量Android應用。