Jetpack-LiveData

夕陽下的奔跑發表於2019-09-03

作用:監聽資料變化,同時感知Activity或Fragment的生命週期

使用

建立一個LiveData的物件,並呼叫observe進行監聽。然後呼叫setValue和postValue進行資料設定,觸發回撥。

public class MainActivity extends AppCompatActivity {
    
    LiveData<String> data = new MutableLiveData<>();
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
		//實現對data的監聽,如果資料改變,會觸發回撥
        data.observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                
            }
        });
    }
    
    //data.setValue(value);
    //data.postValue(value); 改變資料,觸發回撥
}
複製程式碼

關鍵類

類圖:

Jetpack-LiveData
LiveData:抽象類,管理資料,以及觀察者,並與Lifecycle的狀態進行關聯

public abstract class LiveData<T> {
    @SuppressWarnings("WeakerAccess")
    final Object mDataLock = new Object();
    static final int START_VERSION = -1;
    @SuppressWarnings("WeakerAccess")
    static final Object NOT_SET = new Object();

    private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
            new SafeIterableMap<>();

    @SuppressWarnings("WeakerAccess")
    int mActiveCount = 0;
    private volatile Object mData;
    @SuppressWarnings("WeakerAccess") /* synthetic access */
    volatile Object mPendingData = NOT_SET;
    private int mVersion;

    private boolean mDispatchingValue;
    @SuppressWarnings("FieldCanBeLocal")
    private boolean mDispatchInvalidated;
    private final Runnable mPostValueRunnable = new Runnable() {
        @SuppressWarnings("unchecked")
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            setValue((T) newValue);
        }
    };

    public LiveData(T value) {
        mData = value;
        mVersion = START_VERSION + 1;
    }

    public LiveData() {
        mData = NOT_SET;
        mVersion = START_VERSION;
    }

    @SuppressWarnings("unchecked")
    private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) {
            return;
        }
		//是否應該分發
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        observer.mObserver.onChanged((T) mData);
    }

    @SuppressWarnings("WeakerAccess") /* synthetic access */
    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                //分發給對應的觀察者
                considerNotify(initiator);
                initiator = null;
            } else {
                //遍歷觀察者
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    //如果有新資料到,則退出本次分發,重頭開始分發
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        //如果已經onDestroy,不註冊觀察者
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            return;
        }
        //將Observer封裝成LifecycleBoundObserver,與LifecycleOwner繫結
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing != null && !existing.isAttachedTo(owner)) {
            //如果已經新增過,且LifecycleOwner不一樣
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        //已新增過
        if (existing != null) {
            return;
        }
        owner.getLifecycle().addObserver(wrapper);
    }

    @MainThread
    public void observeForever(@NonNull Observer<? super T> observer) {
        assertMainThread("observeForever");
        AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing instanceof LiveData.LifecycleBoundObserver) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        //一直分發資料,不關心Liefcycle的狀態
        wrapper.activeStateChanged(true);
    }

    @MainThread
    public void removeObserver(@NonNull final Observer<? super T> observer) {
        assertMainThread("removeObserver");
        ObserverWrapper removed = mObservers.remove(observer);
        if (removed == null) {
            return;
        }
        removed.detachObserver();
        //將狀態置為不再分發新資料
        removed.activeStateChanged(false);
    }

    @SuppressWarnings("WeakerAccess")
    @MainThread
    public void removeObservers(@NonNull final LifecycleOwner owner) {
        assertMainThread("removeObservers");
        for (Map.Entry<Observer<? super T>, ObserverWrapper> entry : mObservers) {
            //移除跟LifecycleOwner繫結的觀察者
            if (entry.getValue().isAttachedTo(owner)) {
                removeObserver(entry.getKey());
            }
        }
    }
	//非同步將設定資料的任務放到主執行緒訊息佇列,如果同時呼叫多次,只有最後一次的資料會生效
    protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        //如果有任務在訊息佇列中,不再放到佇列中,避免回撥執行多次
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }
	//同步設定資料
    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }

    @SuppressWarnings("unchecked")
    @Nullable
    public T getValue() {
        Object data = mData;
        if (data != NOT_SET) {
            return (T) data;
        }
        return null;
    }

    int getVersion() {
        return mVersion;
    }

    protected void onActive() {

    }

    protected void onInactive() {

    }

    @SuppressWarnings("WeakerAccess")
    public boolean hasObservers() {
        return mObservers.size() > 0;
    }

    @SuppressWarnings("WeakerAccess")
    public boolean hasActiveObservers() {
        return mActiveCount > 0;
    }
}
複製程式碼

ObserverWrapper:觀察者的包裝類,持有觀察者,並跟狀態有關

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();
	//是否跟Lifecycle繫結
    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);
        }
    }
}
複製程式碼

LifecycleBoundObserver:繼承自ObserverWrapper,跟Lifecycle繫結

class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
    @NonNull
    final LifecycleOwner mOwner;

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

    @Override
    boolean shouldBeActive() {
        //生命週期至少onStart之後才能進行分發
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
        //如果已經onDestroy則移除觀察者,並不進行分發
       if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        activeStateChanged(shouldBeActive());
    }

    @Override
    boolean isAttachedTo(LifecycleOwner owner) {
        //判斷LifecycleOwner是否一樣
        return mOwner == owner;
    }

    @Override
    void detachObserver() {
        //移除觀察者
        mOwner.getLifecycle().removeObserver(this);
    }
}
複製程式碼