LiveData 源码分析

注:本文所有代码基于 android.arch.lifecycle 1.0.0-alpha1

在 Lifecycle-aware Components 源码分析 一文中,我们已经分析了 Lifecycle 框架中所有的 lifecyle 事件产生流程以及分发流程。本文将会基于这部分知识来分析 Lifecycle 框架中的 LiveData 组件。

提出问题

结合 LiveData javadoc, LiveData 文档,我们可以了解到 LiveData 主要作用是数据发生变化时通知 Observer,那么 LiveData 是如何实现这部分内容的呢?

LiveData

observe

有监听得先有注册,先来看 observe 方法:

@MainThread
public void observe(LifecycleOwner owner, Observer<T> observer) {
   if (owner.getLifecycle().getCurrentState() == DESTROYED) {
       // ignore
       return;
   }
   LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
   LifecycleBoundObserver existing = mObservers.putIfAbsent(observer, wrapper);
   if (existing != null && existing.owner != wrapper.owner) {
       throw new IllegalArgumentException("Cannot add the same observer"
               + " with different lifecycles");
   }
   if (existing != null) {
       return;
   }
   owner.getLifecycle().addObserver(wrapper);
   wrapper.activeStateChanged(isActiveState(owner.getLifecycle().getCurrentState()));
}

observe 方法需运行在主线程中,执行时会将 Observer 传入 LifecycleBoundObserver,并将 LifecycleBoundObserver 通过 addObserver 注册至 Lifecycle,紧接着调用了 LifecycleBoundObserver 的 activeStateChanged 方法。

LifecycleBoundObserver

接着看 LifecycleBoundObserver:

class LifecycleBoundObserver implements LifecycleObserver {
   public final LifecycleOwner owner;
   public final Observer<T> observer;
   public boolean active;
   public int lastVersion = START_VERSION;
   LifecycleBoundObserver(LifecycleOwner owner, Observer<T> observer) {
       this.owner = owner;
       this.observer = observer;
   }
   @SuppressWarnings("unused")
   @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
   void onStateChange() {
       if (owner.getLifecycle().getCurrentState() == DESTROYED) {
           removeObserver(observer);
           return;
       }
       // immediately set active state, so we'd never dispatch anything to inactive
       // owner
       activeStateChanged(isActiveState(owner.getLifecycle().getCurrentState()));
   }
   void activeStateChanged(boolean newActive) {
       if (newActive == active) {
           return;
       }
       active = newActive;
       boolean wasInactive = LiveData.this.mActiveCount == 0;
       LiveData.this.mActiveCount += active ? 1 : -1;
       if (wasInactive && active) {
           onActive();
       }
       if (LiveData.this.mActiveCount == 0 && !active) {
           onInactive();
       }
       if (active) {
           dispatchingValue(this);
       }
   }
}
static boolean isActiveState(State state) {
   return state.isAtLeast(STARTED);
}

不难看出 onStateChange 会接收所有的 lifecycle 事件。当 LifecycleOwner 的状态处于 STARTED 或 RESUMED 时,传入 activeStateChanged 的值为 true,即 LifecycleBoundObserver 会被标记为激活状态,同时会增加 LiveData 的 mActiveCount 计数。接着可以看到,onActive 会在 mActiveCount 为 1 时触发,onInactive 方法则只会在 mActiveCount 为 0 时触发。这里就与 LiveData javadoc 所描述的完全吻合(In addition, LiveData has onActive() and onInactive() methods to get notified when number of active Observers change between 0 and 1. This allows LiveData to release any heavy resources when it does not have any Observers that are actively observing.)。

dispatchingValue

此后,如果 LifecycleBoundObserver 处于激活状态,则会调用 dispatchingValue:

private void dispatchingValue(@Nullable LifecycleBoundObserver initiator) {
   if (mDispatchingValue) {
       mDispatchInvalidated = true;
       return;
   }
   mDispatchingValue = true;
   do {
       mDispatchInvalidated = false;
       if (initiator != null) {
           considerNotify(initiator);
           initiator = null;
       } else {
           for (Iterator<Map.Entry<Observer<T>, LifecycleBoundObserver>> iterator =
                   mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
               considerNotify(iterator.next().getValue());
               if (mDispatchInvalidated) {
                   break;
               }
           }
       }
   } while (mDispatchInvalidated);
   mDispatchingValue = false;
}

其中 mDispatchingValue, mDispatchInvalidated 只在 dispatchingValue 方法中使用,显然这两个变量是为了防止重复分发相同的内容。

considerNotify

接下来,无论哪个路径都会调用 considerNotify:

private void considerNotify(LifecycleBoundObserver observer) {
   if (!observer.active) {
       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 (!isActiveState(observer.owner.getLifecycle().getCurrentState())) {
       return;
   }
   if (observer.lastVersion >= mVersion) {
       // 数据已经是最新
       return;
   }
   observer.lastVersion = mVersion;
   //noinspection unchecked
   observer.observer.onChanged((T) mData);
}

注:mVersion 代表的是数据变化的次数,下文会补充说明。

显然 considerNotify 的作用就是通知处于激活状态且数据未更新的 Observer 数据已发生变化。

其中 mData 即是 LiveData 当前的数据,默认是一个全局 Object:

private static final Object NOT_SET = new Object();
private Object mData = NOT_SET;

可能会有人担心当 LiveData 的 mData 未发生变更时,第一次调用 observe 会将 NOT_SET 传递到 Observer 中。事实上并不会,因为 LiveData 的 mVersion 和 LifecycleBoundObserver 的 lastVersion 的默认值均为 START_VERSION:

public abstract class LiveData<T> {
    ...
    static final int START_VERSION = -1;
    private int mVersion = START_VERSION;
    ...
    class LifecycleBoundObserver implements LifecycleObserver {
        ...
        public int lastVersion = START_VERSION;
        ...
    }
    ...
}

在 observer.lastVersion >= mVersion 判断时就会直接返回而不执行 observer.observer.onChanged((T) mData)。

setValue

再来看 setValue:

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

setValue 与 observe 方法一样均需要在主线程上执行,当 setValue 的时候 mVersion 的值会自增,并通知 Observer 数据发生变化。

postValue

setValue 还有另一个替代的方法 postValue:

protected void postValue(T value) {
   boolean postTask;
   synchronized (mDataLock) {
       postTask = mPendingData == NOT_SET;
       mPendingData = value;
   }
   if (!postTask) {
       return;
   }
   AppToolkitTaskExecutor.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);
   }
};

其中 AppToolkitTaskExecutor 是通过一个以 Main Looper 作为 Looper 的 Handler 将 mPostValueRunnable 运行在主线程上,所以 postValue 可以运行在任意线程上,而 Observer 的 OnChange 回调会执行在主线程上。

observeForever

最后再看下 observeForever:

@MainThread
public void observeForever(Observer<T> observer) {
   observe(ALWAYS_ON, observer);
}
private static final LifecycleOwner ALWAYS_ON = new LifecycleOwner() {
   private LifecycleRegistry mRegistry = init();
   private LifecycleRegistry init() {
       LifecycleRegistry registry = new LifecycleRegistry(this);
       registry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
       registry.handleLifecycleEvent(Lifecycle.Event.ON_START);
       registry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
       return registry;
   }
   @Override
   public Lifecycle getLifecycle() {
       return mRegistry;
   }
};

可以看到,observeForever 将 Observer 注册了在一个永远处于 RESUMED 的 LifecycleOwner 中,所以通过 observeForever 注册的 Observer 需要通过 removeObserver 来取消数据变化的监听。

总结

至此,我们已经明白 LiveData 主要是通过 LifecycleBoundObserver 与 Lifecycle 结合来控制数据的分发。

LiveData 的代码比 Lifecycle 要简单得多,主要是有了 Lifecycle 部分的分析作为基础,看起来很轻松。因为简单,所以文章记录的时候流水账比较严重,本来不打算发的 (:з」∠) 不过写都写了,扔出来占个位置吧。

喜欢的话请帮忙转发一下能让更多有需要的人看到吧,有些技术上的问题大家可以多探讨一下。

以上Android资料以及更多Android相关资料及面试经验可在QQ群里获取:936903570。有加群的朋友请记得备注上CSDN,谢谢

猜你喜欢

转载自blog.csdn.net/weixin_43901866/article/details/86629390