LiveData原理分析

1 LiveData簡介

大部分Android應用會從網(wǎng)絡或SQLite數(shù)據(jù)庫存取數(shù)據(jù),并根據(jù)數(shù)據(jù)更新界面。為了避免ANR,主線程中不能存取數(shù)據(jù)。而后臺線程中無法更新界面。通常的做法是讓后臺線程將數(shù)據(jù)通過Handler傳遞給主線程。但是當界面較為復雜時,使用Handler這種方式變得非常復雜。為了簡化界面更新的工作,Google在Jetpack中提供了LiveData組件。LiveData具有保證UI和狀態(tài)一致、避免內(nèi)存泄漏、避免手動管理生命周期等優(yōu)點。

2 LiveData用法

LiveData是一個在線程間傳遞數(shù)據(jù)的容器。當后臺線程得到數(shù)據(jù)后,通過postValue()方法投遞數(shù)據(jù)。其他線程通過getValue()得到數(shù)據(jù)。為了通知其他線程,LiveData采用的觀察者模式。通過observe()方法,主線程可以在數(shù)據(jù)更新后立即得到通知。下面是一個簡單的例子:

public class BackgroundThread extends Thread {

        public BackgroundThread(LiveData<Data> aLiveData) {
                liveData = aLiveData;
        }

        @Override
        public void run() {
                Data data = readDataFromFile();
                liveData.postValue(data);
        }
}

public MainActivity extends AppCompatActivity {

        private LiveData<Data> liveData = new MutableLiveData<>();
        private BackgroundThread thread = new BackgroundThread(liveData);
        private TextView textview;

        @Override protected onCreate(Bundle bundle) {
                // ...

                liveData.observe(this, new Observer<Data>() {
                                @Override
                                public void onChanged(Data data) {
                                        textview.setText(data.getText());
                                }});
        }
}

從例子里可以看到,observe()方法有兩個參數(shù),第二個參數(shù)是觀察者。那么第一個參數(shù)是什么呢?第一個參數(shù)的類型是LifecycleOwner,加入LifecycleOwner的目的是自動管理Activity生命周期。這一點在后面會進行介紹。

LiveData類定義在android.arch.lifecycle中,使用時需要在build.gradle引入依賴項:

implementation "android.arch.lifecycle:extensions:1.1.1"

3 數(shù)據(jù)的傳遞

實際上LiveData傳遞數(shù)據(jù)的方法也是通過Handler。在postValue()方法中,LiveData調(diào)用ArchTaskExecutor.postToMainThread(),將一個Runnable對象傳遞給主線程。這個Runnable對象調(diào)用setValue()對數(shù)據(jù)進行更新。

更新數(shù)據(jù)的時候,LiveData首先將版本號加1,然后遍歷觀察者。如果觀察者處于活躍狀態(tài)(Lifecycle.State是STARTED或RESUMED),并且觀察者的版本號小于LiveData,LiveData會調(diào)用觀察者的onChanged()方法進行通知。

4 生命周期管理

這一段簡單介紹一下生命周期管理。當觀察者的生命周期不是STARTED或RESUMED時,數(shù)據(jù)更新不會進行通知。這是怎么實現(xiàn)的呢?在調(diào)用observe()時,第一個參數(shù)是LifecycleOwner,第二個參數(shù)是Observer。LiveData建立一個LifecyleBoundObserver對象,將這兩個參數(shù)綁定到一起,來接收Lifecycle的生命周期更新和LiveData的數(shù)據(jù)更新。LifecycleBoundObserver是一個的內(nèi)部類,它持有了LiveData引用。當生命周期發(fā)生變化(LifecycleRegistry.handleLifecyleEvent)時,LifecycleBoundObserver調(diào)用LiveData的dispatchingValue()方法,獲取最新數(shù)據(jù)。

5 Lifecycle

Lifecycle生命了Android生命周期。Lifecycle包括6個狀態(tài)和7個事件,分別是:

| 狀態(tài) |
| DESTROY |
| INITIALIZED |
| CREATED |
| STARTED |
| RESUMED |

| 事件 |
| ON_CREATE |
| ON_START |
| ON_RESUME |
| ON_PAUSE |
| ON_STOP |
| ON_DESTROY |
| ON_ANY |

6 Room

Room是Jetpack提供的SQLite ORM工具。Room中存取數(shù)據(jù)的方法都是阻塞的,要在后臺執(zhí)行,因此非常適合與LiveData配合使用。Room中定義的Dao可以返回LiveData,當SQLite查詢返回后,對界面進行更新。

7 ViewModel

另一個經(jīng)常和LiveData搭配使用的是ViewModel。ViewModel用于管理Activity或Fragment中的各LiveData對象。可以把ViewModel看成是LiveData的集合。ViewModel的優(yōu)點是可以和Activity或Fragment綁定在一起,并且在配置改變引起的Activity/Fragment銷毀時,ViewModel仍然可以持有狀態(tài)。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容