Android Jetpack之LiveData源碼分析

Android Jetpack之LiveData源碼分析

LiveData的使用會結合Lifecycles和ViewModel一塊兒使用,不瞭解兩者的,建議先看這兩篇文章: Android Jetpack之ViewModel源碼分析 Android Jetpack之Lifecycles源碼分析java

LiveData 簡介

LiveData 是保存數據對象的類,經過註冊監聽器Observer 監聽數據的變化。LiveData最大的優點:LiveData 是感知Activity、Fragment等生命週期的組件,Observer 能夠指定監聽的生命週期(Lifecycle)對象。當 Observer 的 Lifecycle 對象處於 STARTED 或者 RESUMED 狀態的時候, LiveData 處於活動狀態,在活動狀態下數據變化會通知到相應的Observer。當相應Lifecycle對象的狀態改變爲DESTROYED時移除觀察者,因此避免形成內存泄漏。固然也能夠不和Lifecycles綁定,使用observeForever(Observer)方法註冊一個沒有關聯生命週期全部者對象的觀察者,觀察者老是處於活動狀態,所以數據變化事件老是會被通知到,能夠經過調用removeObserver(Observer) 刪除observer。 官網指導連接Android jetpack之LiveDataandroid

LiveData的簡單使用

2.一、建立一個ViewModel類

建立一個ViewModel類,裏面有LiveData實例來保存數據。使用ViewModel是爲了在屏幕旋轉等操做下時能夠恢復現場數據。bash

class MyLiveDataViewModel : ViewModel(){
    var liveData: MutableLiveData<String>?= null
        get() {
            if(field == null){
                field = MutableLiveData()
            }
            return field
        }

}
複製代碼

2.2 建立observer

(1)代碼1: 建立LiveDataActivity實現LifecycleOwner接口,爲了Observer和組件的生命週期綁定。 (2)代碼2: 獲取定義的MyLiveDataViewModel實例 (3)代碼3: 建立定義onChanged()方法的Observer對象,在數據變化時更新UI頁面。 (4)代碼4: LiveData訂閱觀察,將LiveData和Lifecycles、Observer綁定, (5)代碼5: LiveData設置新數據,通知觀察者更新數據。能夠在子線程中執行。 完整代碼以下:數據結構

//代碼1
class LiveDataActivity : AppCompatActivity(),LifecycleOwner{
    private lateinit var lifecycleRegistroy: LifecycleRegistry
    private var coun : Int by Delegates.notNull<Int>()
    override fun getLifecycle(): Lifecycle {
        return lifecycleRegistroy
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_live_data)
        lifecycleRegistroy = LifecycleRegistry(this)
        coun = 0
        //代碼2
        var viewModel = ViewModelProviders.of(this).get(MyLiveDataViewModel::class.java)
        //代碼3
        val observer = Observer<String>{
            text.text = it
        }

        button.setOnClickListener {
        	//代碼5
            viewModel.liveData?.postValue("changed !!!!"+coun++)}
        //代碼4
        viewModel.liveData?.observe(this,observer)
    }
}
複製代碼

源碼分析

3.1 LiveData.observe方法

在Activity中經過添加observe方法將Lifecycles和Observer綁定起來。下面咱們來分析該方法。該方法有兩個參數:併發

  1. LifecycleOwner是爲了處理生命週期改變。
  2. Observer是爲了監聽LiveData的數據變化的觀察者。

下面來分析observe方法內部的實現原理:app

  1. 在observe方法內部判斷了Lifecycler的當前狀態,若是State處於DESTROYED,即觀察者處於DESTROYED狀態時,不作任何處理。
  2. 若是處於活躍狀態,則建立LifecycleBoundObserver實例保存傳入的LifecycleOwner和Observer,並保存在mObservers中。SafeIterableMap存儲的是鍵值對的形式,使用的是SafeIterableMap數據結構,不熟悉的能夠參考Android Jectpack之Lifecycles源碼分析。KEY是Observer,VALUE是LifecycleBoundObserver類。
  3. 若是Observer對象已經存在對應的Lifecycles則拋出異常。
  4. 爲LifecycleOwner添加生命週期的觀察者,其實就是LifecycleBoundObserver類,該類實現了GenericLifecycleObserver接口,能夠經過onStateChanged方法監聽LifecycleOwner的State變化。
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        owner.getLifecycle().addObserver(wrapper);
    }
複製代碼

3.2 LifecycleBoundObserver類

3.2.1 LifecycleBoundObserver類

經過observe.observer的分析咱們知道,內部主要是用了LifecycleBoundObserver類,下面分析該類ide

  1. LifecycleBoundObserver 繼承自 ObserverWrapper 並且實現 GenericLifecycleObserver接口,而 GenericLifecycleObserver 接口又繼承自 LifecycleObserver 接口。在Lifecycles的源碼分析咱們知道,實現了LifecycleObserver接口並且 LifecycleOwner 的觀察者裏能夠獲取 LifecycleOwner 的狀態。
  2. shouldBeActive方法表示只有STARTED,RESUMED纔是活躍狀態
  3. 當Lifecycles的State發生變化會回調onStateChanged方法,當State爲DESTROYED是,則移除觀察氣Observer。裏面調用的是LiveData的removeObserver方法(下面會分析)。
  4. 當State非DESTROYED,則調用ObserverWrapper的activeStateChanged方法。
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
        @NonNull
        final LifecycleOwner mOwner;

        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
            super(observer);
            mOwner = owner;
        }

        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

        @Override
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            activeStateChanged(shouldBeActive());
        }

        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }

        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }
複製代碼

3.2.2 ObserverWrapper類

LifecycleBoundObserver 繼承自 ObserverWrapper而且在onStateChanged中調用了activeStateChanged的方法,下面來分析一下ObserverWrapper類。函數

  1. ObserverWrapper 在LifecycleOwner活躍狀態改變時回調onActive和onInactive方法。Owner爲活躍狀態時回調onActive() ,當Owner未活躍狀態時回調onInactive()
  2. 當狀態變爲活躍態是,LiveData.this.mActiveCount加1
  3. 當變成活躍態時,會執行dispatchingValue方法,通知Observer併發送最新的數據。(源碼分析在下一節)
  4. onActive() :當 LiveData 具備活動狀態的 Observer 的時候會調用這個函數。當咱們自定義LiveData時,能夠在這個函數中處理本身的業務邏輯
  5. onInactive():當 LiveData 沒有活動狀態的 Observer 的時候會調用這個函數。當咱們自定義LiveData時,能夠在這個函數中處理本身的業務邏輯,不如一些非後臺的操做或者變量的釋放。
private abstract class ObserverWrapper {
        final Observer<? super T> mObserver;
        boolean mActive;
        int mLastVersion = START_VERSION;

        ObserverWrapper(Observer<? super T> observer) {
            mObserver = observer;
        }

        abstract boolean shouldBeActive();

        boolean isAttachedTo(LifecycleOwner owner) {
            return false;
        }

        void detachObserver() {
        }

        void activeStateChanged(boolean newActive) {
            if (newActive == mActive) {
                return;
            }
            // immediately set active state, so we'd never dispatch anything to inactive // owner mActive = newActive; boolean wasInactive = LiveData.this.mActiveCount == 0; LiveData.this.mActiveCount += mActive ? 1 : -1; if (wasInactive && mActive) { onActive(); } if (LiveData.this.mActiveCount == 0 && !mActive) { onInactive(); } if (mActive) { dispatchingValue(this); } } } 複製代碼

3.2.3 AlwaysActiveObserver類

使用observeForever(Observer)方法註冊一個沒有關聯生命週期全部者對象的觀察者,觀察者老是處於活動狀態,所以數據變化事件老是會被通知到。下面咱們來看一下其中的原理:oop

public void observeForever(@NonNull Observer<? super T> observer) {
        assertMainThread("observeForever");
        AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing != null && existing instanceof LiveData.LifecycleBoundObserver) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        wrapper.activeStateChanged(true);
    }
複製代碼

在observeForever使用的AlwaysActiveObserver該類不一樣於LifecycleBoundObserver類,沒有實現GenericLifecycleObserver接口,因此不能感激組件的生命週期變化,而且其實該方法,也沒有LifecycleOwner的形參。在AlwaysActiveObserver 的類內部的shouldBeActive方法用於返回ture,而且在observeForever內部將ObserverWrapper.mActive設置爲true,也就是標明永遠是處於活躍狀態,因此Observer是一直能夠觀察數據變化的。源碼分析

private class AlwaysActiveObserver extends ObserverWrapper {

        AlwaysActiveObserver(Observer<? super T> observer) {
            super(observer);
        }

        @Override
        boolean shouldBeActive() {
            return true;
        }
    }
複製代碼

3.3 LiveData類

在Activity中,經過postValue或者setValue改變LivwData的數據,在經過Observer,觀察LIveData數據的變化。經過上面的分析,咱們已經知道了Observer是如何和組件的生命週期綁定起來的,下面咱們就分析一下,LiveData的數據更新是如何通知到Observer 的。

3.3.1 setValue方法

先來分析一下setValue()方法,setValue()必須在主線程中調用,不然會報錯,而postValue則沒有這個檢查。看到有無post的區別,第一反應就是是invalidate和postInvalidate的區別。

protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }
複製代碼
  1. 調用assertMainThread()檢查是否在主線程。
  2. 把更新的數據賦給mData。
  3. 調用 dispatchingValue()方法並傳入null,將數據分發給全部觀察者。dispatchingValue若是傳入null則是全部的觀察者,若是是具體的ObserverWrapper對象,則通知到具體的Observer。

3.3.2 dispatchingValue方法

下面在分析一下dispatchingValue方法。

  1. dispatchingValue參數傳null將會通知全部的觀察者,
  2. dispatchingValue不傳null只會通知傳入的觀察者。
  3. 在代碼1處,經過遍歷 mObservers ,將全部的 LifecycleBoundObserver 取出,對每一個觀察者調用considerNotify()方法,considerNotify方法就是真正通知到觀察者的代碼了。
void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                considerNotify(initiator);
                initiator = null;
            } else {
               //代碼1
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }
複製代碼

3.3.4 considerNotify方法

  1. 若是ObserverWrapper的狀態爲非活躍態則直接返回。這就驗證了只有STARTED、RESUMED才能接受數據的結論
  2. considerNotify方法中調用mObserver的onChange方法,從而通知Observer更新數據。
private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) {
            return;
        }
        // Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet. // // we still first check observer.active to keep it as the entrance for events. So even if // the observer moved to an active state, if we've not received that event, we better not
        // notify for a more predictable notification order.
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //noinspection unchecked
        observer.mObserver.onChanged((T) mData);
    }

複製代碼

3.3.5 postValue方法

postValue方法能夠在非主線程中更新數據。主要是經過ArchTaskExecutor和DefaultTaskExecutor切換到主線程中。而後回調到Runnable方法中,在Runnable的run方法其實也是調用了setValue方法來實現通知觀察者更新數據的邏輯的。

protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }
複製代碼
private final Runnable mPostValueRunnable = new Runnable() {
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            //noinspection unchecked
            setValue((T) newValue);
        }
    };

複製代碼

3.3.6 ArchTaskExecutor類

ArchTaskExecutor是單例模式。繼承自TaskExecutor。

public static ArchTaskExecutor getInstance() {
        if (sInstance != null) {
            return sInstance;
        }
        synchronized (ArchTaskExecutor.class) {
            if (sInstance == null) {
                sInstance = new ArchTaskExecutor();
            }
        }
        return sInstance;
    }

複製代碼

當調用postToMainThread切換線程是,內部其實是執行了DefaultTaskExecutor類的postToMainThread方法。

public void postToMainThread(Runnable runnable) {
        mDelegate.postToMainThread(runnable);
    }
複製代碼

DefaultTaskExecutor類的postToMainThread內部經過Handler實現線程的切換。

@Override
    public void postToMainThread(Runnable runnable) {
        if (mMainHandler == null) {
            synchronized (mLock) {
                if (mMainHandler == null) {
                    mMainHandler = new Handler(Looper.getMainLooper());
                }
            }
        }
        //noinspection ConstantConditions
        mMainHandler.post(runnable);
    }

複製代碼

3.4 小結

  1. 使用LifecycleOwner的observe() 方法將觀察者對象附加到LiveData對象,將觀察者向LiveData對象訂閱,以便通知LiveData中數據的變化。
  2. 當Lifecycle 沒有處於活動狀態( (STARTED 、RESUMED)),Observer 則不會被通知,即便數據發生了變化,沒有處於活動狀態的 Observer 也不會被通知。
  3. Lifecycle 被銷燬(destroyed)Observer 也自動被刪除,無需用戶手動清理。
  4. 避免內存泄漏:Observer 和 Lifecycle 綁定,能夠感知組件生命週期,因此當 Lifecycle 被銷燬後,Observer 自動被remove避免內粗泄漏。

LiveData高階使用

4.1 轉換LiveData

LiveData 支持簡單的數據變換。

  1. map 是把一個數據類型變換爲另一個數據類型。
  2. switchMap 是把一個數據變化爲另一個 LiveData

使用 Transformation 的好處:若是 Lifecycle 處於未激活狀態,則轉換函數也一樣不會執行。 map實例:

class MyLiveDataViewModel : ViewModel(){
    var liveData: MutableLiveData<User> = MutableLiveData()
        get() {
            return field
        }

}

class User(val name: String,val lastName: String)


class LiveDataActivity : AppCompatActivity(),LifecycleOwner{
    private lateinit var lifecycleRegistroy: LifecycleRegistry
    override fun getLifecycle(): Lifecycle {
        return lifecycleRegistroy
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_live_data)
        lifecycleRegistroy = LifecycleRegistry(this)
        var viewModel = ViewModelProviders.of(this).get(MyLiveDataViewModel::class.java)

        val observer = Observer<String>{
            text.text = it
        }

        button.setOnClickListener {
            var user = User("android","jectpack")
            viewModel.liveData.postValue(user)}

        val userLivaData: LiveData<User> = viewModel.liveData
        val nameLiveData: LiveData<String> = Transformations.map(userLivaData){
            it.name + it.lastName
        }
        nameLiveData.observe(this,observer)
    }
}
複製代碼

switchMap實例:

class LiveDataActivity : AppCompatActivity(),LifecycleOwner{
    private lateinit var lifecycleRegistroy: LifecycleRegistry
    override fun getLifecycle(): Lifecycle {
        return lifecycleRegistroy
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_live_data)
        lifecycleRegistroy = LifecycleRegistry(this)
        var viewModel = ViewModelProviders.of(this).get(MyLiveDataViewModel::class.java)

        val observer = Observer<String>{
            text.text = it
        }

        button.setOnClickListener {
            var user = User("android","jectpack")
            viewModel.liveData.postValue(user)}

        val userLivaData: LiveData<User> = viewModel.liveData
        val nameLiveData: LiveData<String> = Transformations.switchMap(userLivaData){
            getUserName(it)
        }
        nameLiveData.observe(this,observer)
    }
    private fun getUserName(user: User): LiveData<String> {
        val liveData: MutableLiveData<String> = MutableLiveData<String>()
        liveData.value = user.name +" switch map " + user.lastName
        return liveData
    }
}
複製代碼

4.2 MediatorLiveData

MediatorLiveData的做用是合併幾個流到一個流中。 實例代碼:

class LiveDataActivity : AppCompatActivity(),LifecycleOwner{
    private lateinit var lifecycleRegistroy: LifecycleRegistry
    override fun getLifecycle(): Lifecycle {
        return lifecycleRegistroy
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_live_data)
        lifecycleRegistroy = LifecycleRegistry(this)
        var viewModel = ViewModelProviders.of(this).get(MyLiveDataViewModel::class.java)

        val observer = Observer<String>{
            text.text = it
        }

        button.setOnClickListener {
            var user = User("android","jectpack")
            viewModel.liveData.postValue(user)}

        val userLivaData: LiveData<User> = viewModel.liveData
        val nameLiveData: LiveData<String> = Transformations.switchMap(userLivaData){
            getUserName(it)
        }
        var mediatorLiveData: MediatorLiveData<String> = MediatorLiveData()
        mediatorLiveData.addSource(userLivaData){
            mediatorLiveData.value = "first source "
        }
        mediatorLiveData.addSource(nameLiveData){
            mediatorLiveData.value = it + " second source"
        }

        mediatorLiveData.observe(this,observer)
    }
    private fun getUserName(user: User): LiveData<String> {
        val liveData: MutableLiveData<String> = MutableLiveData<String>()
        liveData.value = " "
        return liveData
    }
}
複製代碼
相關文章
相關標籤/搜索