LiveData详解

LiveData原理解析

LiveData是一个数据持有者类,可以在给定的生命周期中观察到。

observe观察数据变化

    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer 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);
    }

observe被要求在主线程调用,并且传递生命周期相关的LifecycleOwner,

  • 检查观察者生命周期状态
  • 组合LifecycleOwner与observer生成LifecycleBoundObserver并以observer为key存起来
  • 限制观察者只能与一个生命周期绑定并且控制不要重复观察
  • 由于Lifecycle.addObserver会回调当前生命周期,所以observe时会收到一次数据变化
  • LifecycleBoundObserver在生命周期销毁时会移除对LiveData的观察,不需要调用者关心解绑时机
  • 数据变化时通过判断Observer的生命周期状态+当前数据版本号判断是否回调数据变化
boolean shouldBeActive() {
    return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
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);
}

observeForever观察数据变化

@MainThread
public void observeForever(@NonNull Observer 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);
}

与observe相似,区别在于

  • observeForever不与生命周期绑定。

  • 记录的观察者为AlwaysActiveObserver

  • 数据变化时判断的Observer的生命周期方法变为不关心生命周期,变化了就回调

    boolean shouldBeActive() {
        return true;
    }
    
  • 不会自动解除绑定,需要主动解除绑定

ObserverWrapper观察者对象

ObserverWrapper是LiveData缓存的观察者对象,它是LifecycleBoundObserver与AlwaysActiveObserver的父类

private abstract class ObserverWrapper {
    final Observer mObserver;
    boolean mActive;
    int mLastVersion = START_VERSION;

    ObserverWrapper(Observer 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);
        }
    }
}
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
    @NonNull
    final LifecycleOwner mOwner;

    LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer 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);
    }
}
private class AlwaysActiveObserver extends ObserverWrapper {

    AlwaysActiveObserver(Observer observer) {
        super(observer);
    }

    @Override
    boolean shouldBeActive() {
        return true;
    }
}

private static void assertMainThread(String methodName) {
    if (!ArchTaskExecutor.getInstance().isMainThread()) {
        throw new IllegalStateException("Cannot invoke " + methodName + " on a background"
                + " thread");
    }
}
  • Lifecycle转化到观察者对象里来讲就是一个mActive(是否活跃)状态,如果活跃,则数据变化我就回调mObserver的onChanged方法,如果不活跃则等你重新活跃了再回调给你数据变更。
  • shouldBeActive() 观察者是否活跃
  • isAttachedTo(LifecycleOwner owner) 判断是否已经设置过监听
  • detachObserver() 观察者被移除时回调 LifecycleBoundObserver在detachObserver时会移除对lifecycle的监听
  • activeStateChanged(boolean newActive) 活跃状态变更时回调

setValue

@MainThread
protected void setValue(T value) {
    assertMainThread("setValue");
    mVersion++;
    mData = value;
    dispatchingValue(null);
}

更新LiveData数据,被要求在主线程调用,调用后数据及数据版本会变化,随后通知观察者

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, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                considerNotify(iterator.next().getValue());
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;
}

该方法也做了并发兼容,并支持回调指定的ObserverWrapper,用于在ObserverWrapper从非活跃变成活跃状态并且数据版本发生变化时回调自身。

postValue

protected void postValue(T value) {
    boolean postTask;
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        mPendingData = value;
    }
    if (!postTask) {
        return;
    }
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

postValue也是更新LiveData数据,只是该方法支持在子线程调用,调用后通过往主线程Handle抛mPostValueRunnable调用setValue实现数据更新

private final Runnable mPostValueRunnable = new Runnable() {
    @Override
    public void run() {
        Object newValue;
        synchronized (mDataLock) {
            newValue = mPendingData;
            mPendingData = NOT_SET;
        }
        //noinspection unchecked
        setValue((T) newValue);
    }
};

若产生并发则通过替换mPendingData的值来更新数据,而不会重复往主线程抛setValue方法。

LiveData的缺点

LiveData的特性是观察者只关心数据变化的最终值,如果你不太关心数据变化的中间值,只要数据变化了能通知到你最新的值的话LiveData已经够用了,甚至项目中它已经可以取代事件总线的地位。
但如果你需要数据的每一次变化都通知到你的话,就不要用LiveData了。以下场景存在数据丢失的问题

  • postValue高并发情况下只会修改mPendingData值,而不会每次都调用setValue
  • observe更是存在该问题,非活跃状态变成活跃状态时只会收到当前最新值的一次变更通知

只有observeForever+setValue没有这种问题,条件有些苛刻,不了解原理的话容易踩坑。

你可能感兴趣的:(LiveData详解)