关于LiveData 的源码分析

前言

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

提出问题

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

LiveData

observe

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

@MainThread

public void observe(LifecycleOwner owner, Observer 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 observer;

  public boolean active;

  public int lastVersion = START_VERSION;

  LifecycleBoundObserver(LifecycleOwner owner, Observer 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, 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 {

    ...

    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 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核心知识笔记2020》分享

前段时间我和圈子里的几位架构师朋友一起闲聊时的突发奇想,我们在学习Android开发的时候或多或少也受到了一些前辈的指导,所以想把这份情怀延续下去。三个月后,这套资料就出来了,需要这份资料的朋友加Android学习交流群1049273031即可获取。

你可能感兴趣的:(关于LiveData 的源码分析)