Android LiveData 源码实现

LiveData 在项目中时常用到,但是对其源码解读不深,所以深入了解一下。

MutableLiveData<Integer> intLiveData = new MutableLiveData<>();
intLiveData.setValue(12);
intLiveData.observe(this, integer -> {
    Log.d("Main", "integer " + integer);
});

上面是LiveData的普通用法,根据用法来追踪代码实现。

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);
    }
}

重写了 LiveData 的 postValue 和 setValue 方法,在LiveData中这两个方法是 protected 修饰的,所以外部无法直接调用。

LiveData 虽然有abstract修饰,但是并没有一个抽象方法需要它的子类去实现,感觉很奇怪。

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

这个方法被声明要在主线程调用,子线程中可以通过 postValue() 来修改,这个后面再讲。

  1. assertMainThread 这个方法用于判断当前线程是否为主线程,实现方式是 Looper.getMainLooper.getThread == Thread.currentThread()
  2. mVersion 记录LiveData.mData被修改次数
  3. mData是LiveData中实际保存的值
  4. dispatchingValue() 通知观察者,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<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                considerNotify(iterator.next().getValue());
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;
}

通过上面的方法知道 initiator 为 null. 所以会走 else . mObservers 是一个SafeIterableMap对象,看命名就知道是遍历安全的Map. 内部是一个 WeakHashMap, 本身实现了 Iterable 接口。

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);
}

到这一步需要说一下,可以讲 ObserverWrapper 看成一个观察者。

  1. 那么观察者再被通知前,要做两个判断。一个是 mActive 判断,就是当前观察者是否是活的状态;另一个是对当前状态的再次确认。
  2. 当这两个条件都满足之后再判断 观察者上次变动的 version 如果大于等于当前更新的 version 则不更新。
  3. 执行更新操作。

总结

上述过程是LiveData.setValue()后的代码逻辑,其实就是观察者模式,只不过观察者再被通知前做了一些判断。接下来会就是观察者的实现。

observe() 实现
@MainThread
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);
}
  1. 一般都会在 Activity 和 Fragment 中调用 observe 方法,所以传递的 LifecycleOwner 就是当前 Activity/Fragment. 然后就是判断是否销毁,如果销毁则直接 return
  2. 创建 LifecycleBoundObserver 观察者对象并 put 到 mObservers 中。
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);
    }
}
  1. 这个类实现了 LifecycleEventObserver 接口,也就是说,当LifecycleOwner生命周期变化时它会收到通知。‘
  2. 在onStateChanged方法中,如果当前组件生命周期执行到 DESTROYED , 那么就会把当前观察者移除。不然的话就会调用 activeStateChanged() 方法,这个方法在父类 ObserverWrapper 中定义。
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);
    }
}

这个方法比较简单,先判断状态是否变化,变化后更新状态,如果新状态是 active 那么还会调用 dispatchingValue() 去通知观察者值发生了变化。方法中参数是当前观察者,那么就不会从 mObservers 中遍历取所有的观察者,而是直接更新当前观察者。

observeForever()

@MainThread
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);
}

LiveData还有一个 observeForever 方法,这个方法是说只要值变化,就通知我,不需要判断生命周期变化。其实内部实现也简单。

private class AlwaysActiveObserver extends ObserverWrapper {
    AlwaysActiveObserver(Observer<? super T> observer) {
        super(observer);
    }
    @Override
    boolean shouldBeActive() {
        return true;
    }
}

wrapper.activeStateChanged(true) 和对 shouldBeActive 的重写,导致观察者的拦截条件都不成立,所以会一直通知。

postValue() 的实现
protected void postValue(T value) {
    boolean postTask;
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        mPendingData = value;
    }
    if (!postTask) {
        return;
    }
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
  1. 因为 postValue() 是为子线程设计的,所以考虑到了线程同步
  2. 设置 mPendingData 为要更新的值并通过 ArchTaskExecutor 进行更新
@Override
public void postToMainThread(Runnable runnable) {
    mDelegate.postToMainThread(runnable);
}

在 ArchTaskExecutor 中调用代理类的 postToMainThread(). mDelegate 是一个 DefaultTaskExecutor 对象。

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

DefaultTaskExecutor.postToMainThread() 内部是通过 MainHandler 实现的。在回到LiveData中的runnable参数

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

总结

到这 LiveData 就整体就了解了,拆分成观察者和被观察者可以更方便的理解 LiveData 的设计。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值