android Jetpack LiveData用法介紹

LiveData用法介紹

LiveData是Android Jetpack裏的一個組件庫,它具備感知activity和fragment生命週期的功能,使用觀察者模式設置數據並確保數據在activity和fragment正確的生命週期內更新ui,提高app性能,並防止app crashjava

先來看一個很是簡單的例子android

class LiveDataActivity : AppCompatActivity() {

    var liveData: MutableLiveData<String>? = null
    var disposable: Disposable? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_livedata)
        liveData = MutableLiveData()
        // 觀察數據的變化,只有在界面可見的時候纔會回調(即onStart或onResume狀態)
        liveData!!.observe(this, Observer {
            tv_text.text = it
        })

        loadData()
    }

    override fun onDestroy() {
        super.onDestroy()
        disposable?.dispose()
    }

    private fun loadData() {
        disposable = Flowable.interval(1, 1, TimeUnit.SECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                // 更新數據
                liveData?.value = it.toString()
            }
    }
}
複製代碼

LiveData的用法很是簡單,首選new一個LiveData對象,而後經過observe方法添加一個Observer,並實現Observer接口的onChanged方法,最後在數據更新的時候使用livedatasetValue方法更新數據便可;調用setValue方法的時候,若是當前Activity處於onStartonResume狀態,則會調用ObserveronChanged回調,不然先緩存數據,當Activity從新回到onStartonResume狀態時,再調用ObserveronChanged回調(Activity destroy時 會自動remove Observer,因此不須要咱們手動remove)git

LiveData 幾個比較重要的方法介紹

  • setValue(T value)github

    必須在 UI Thread 中調用,更新數據,同時當Activity處於onStartonResume狀態時會調用ObserveronChanged回調數據庫

  • postValue(T value)緩存

    跟setValue()同樣,惟一的區別就是能夠 非UI Thread 中調用,而後經過handler post在UI Thread中回調網絡

  • observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)app

    這是一個很是經常使用的方法, 用於添加一個Observer,監聽數據的變化; LifecycleOwner 通常是activity 或 fragment對象,使其LiveData能夠感知其生命週期,只有在onStartonResume狀態時會調用ObserveronChanged回調, 在destroy時 remove Observer異步

  • observeForever(@NonNull Observer<? super T> observer)ide

    跟observe方法差很少,惟一的區別是沒辦法感知activity 或 fragment生命週期;即只要有數據更新就立馬調用ObserveronChanged回調,而且須要手動remove Observer;這個方法對於Transformation(數據轉換)很是有用,下面會介紹到

  • removeObservers(@NonNull final Observer<? super T> observer)

    這個方法很簡單,就是刪除某個observer

  • onActive()

    這是LiveData的一個回調方法,當observer的數量由0變成1的時候,會調用

  • onInactive()

    這是LiveData的一個回調方法,當observer的數量由1變成0的時候,會調用

MutableLiveData 介紹

MutableLiveData 比較簡單,通常沒什麼特殊需求,用MutableLiveData就能夠,他的源碼實現也很是簡單

public class MutableLiveData<T> extends LiveData<T> {
    @Override
    public void postValue(T value) {
        super.postValue(value);
    }

    @Override
    public void setValue(T value) {
        super.setValue(value);
    }
}
複製代碼

只是將LiveDataprotected修飾postValuesetValue的方法改爲了public

用法就跟上面的demo同樣

MediatorLiveData 介紹

MediatorLiveData繼承MutableLiveData, 並提供addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged)方法監聽LiveData的數據更新,而後作一層處理或直接通知給最外層的Observer

先看一下源碼裏的example, 只處理前10次數據的變化

LiveData<String> liveData1 = ...;
var liveDataMerger = MediatorLiveData<String>()
liveDataMerger.addSource(liveData1, object: Observer<String> {
    var count = 1
    override fun onChanged(t: String) {
        count++
        // 在這裏更新liveDataMerger的數據;所以能夠在這裏對數據作一些額外的處理以後再更新
        liveDataMerger.value = t
        if (count > 10) {
            liveDataMerger.removeSource(liveData1)
        }
    }
})
複製代碼

同時它還能夠監聽多個LiveData的變化

val liveData1 = MutableLiveData<String>()
val liveData2 = MutableLiveData<String>()
var liveDataMerger = MediatorLiveData<String>()
liveDataMerger.addSource(liveData1, Observer { liveDataMerger.value = it })
liveDataMerger.addSource(liveData2, Observer { liveDataMerger.value = it })
// 只要liveData1和liveData2數據有更新就會通知Observer更新ui
liveDataMerger.observe(this, Observer {
    tv_text.text = it
})
複製代碼

其實MediatorLiveData最經常使用的用法是結合Transformation來使用,下面將介紹Transformation的用法

Transformation 轉換

Transformation內部原理使用MediatorLiveData實現的

有的時候咱們須要對當前data 轉換成咱們須要的另外一種data

好比rxjavamap方法

Flowable.range(1, 10)
	.map { "index: $it" }
	.subscribe {
		
	}
複製代碼

再好比 kotlin自帶的map擴展方法

val list = listOf(1, 2, 3, 4).map {
    "index: $it"
}
複製代碼

LiveData 也提供了相似的map功能

// 建立LiveData
val userLiveData: LiveData<User> = MutableLiveData<User>()
val userName: LiveData<String> = Transformations.map(userLiveData) {
    user -> "${user.name} ${user.lastName}"
}
//觀察數據的更新
userName.observe(this, Observer {
    tv_text.text = it
})
...

// 更新數據
userLiveData.value = User("zhang", "san")
複製代碼

LiveData 也提供了switchMap方法轉換數據,它與map惟一的不一樣是將data轉換成一個LiveData<T>,所以在轉換過程當中能夠繼續作異步操做請求數據等,他跟rxjavaflatmap方法有點像

// 先使用room數據庫定義一個UserDao example
@Dao
abstract class UserDao {
    @Query("select * from tab_user where uid = :uid")
    abstract fun getById(uid: Long): LiveData<User>
}	
...

private fun getUser(id: String): LiveData<User> {
	// 可使用room數據查詢user對象
   // return AppDataBase.getUserDao().getUser(id)
   // 你也能夠髮網絡請求查詢user對象
   return object: LiveData<User>() {
        override fun onActive() {
            super.onActive()
            // 模擬網絡請求數據
            Flowable.timer(3, TimeUnit.SECONDS)
                .subscribe {
                    postValue(User("zhang", "san"))
                }
        }
    }
}

...
val userId: LiveData<String> = MutableLiveData<String>()
val user = Transformations.switchMap(userId) { id -> getUser(id) }

//觀察數據的更新
user.observe(this, Observer {
    tv_text.text = "${it.name} ${it.name}"
})
...
// 更新數據
userId.value = "001"
複製代碼

LiveData使用起來比較簡單,功能就介紹到這裏,建議查看一下官方demo 學習結合其它library的用法

相關文章
相關標籤/搜索