Lifecycle 解惑

一、Lifecycle & LifecyclRegistry

1. Lifecycler

Lifecycle 是一个抽象类,它的结构很简单:

  • 一系列生命周期事件的枚举定义:EventON_CREATE...ON_DESTROY, ON_ANY
  • 一系列当前所处状态的定义:StateDESTROYEDINITIALIZEDCREATEDSTARTEDRESUMED
  • 添加、移除观察者的 addObserverremoveObserver 方法
    上面的前两点其实是有关联性的,是由 事件的变化 驱动 状态的变化。它们之间的关系如下图所示:
    image.png

我们来看看系统源码中是如何表现上面关系的:
INITIALIZED 是一个初态,因此在 Lificycle 的唯一子类 LifecycleRegistry 的构造函数中就将 Lifecycle 的初始状态设置为 INITIALIZED

public LifecycleRegistry(@NonNull LifecycleOwner provider) {
    mLifecycleOwner = new WeakReference<>(provider);
    mState = INITIALIZED;
}

方法 RegistryLifecycle.handleLifecycleEvent(Lifecycle.Event) 是统一接收 Event 并将 State 状态流转到相应值的地方。

public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    State next = getStateAfter(event);
    moveToState(next);
}

我们再看 getStateAfter 方法,其中写死了上图中状态流转的对应关系:

static State getStateAfter(Event event) {
    switch (event) {
        case ON_CREATE:
        case ON_STOP:
            return CREATED;
        case ON_START:
        case ON_PAUSE:
            return STARTED;
        case ON_RESUME:
            return RESUMED;
        case ON_DESTROY:
            return DESTROYED;
        case ON_ANY:
            break;
    }
    throw new IllegalArgumentException("Unexpected event value " + event);
}

而调用 handleLifecycleEvent 的地方也是 Fragment/Activity 生命周期回调的地方,这样就把生命周期回调 → EventState 绑定了起来:

image.png

  • Event.ON_CREATE 的发射是在生命周期回调 onCreate 之后,但是 Event.ON_DESTROY 的发射是在生命周期回调 onDestroy 之前。事实上,所有的创建事件都在生命周期回调之后,所有的销毁事件都在生命周期回调之前。
// androidx.fragment.app.Fragment
void performCreate(Bundle savedInstanceState) {
   mChildFragmentManager.noteStateNotSaved();
   // 标记当前的生命周期状态
   mState = CREATED;
   mCalled = false;
   mSavedStateRegistryController.performRestore(savedInstanceState);
   // 生命周期回调
   onCreate(savedInstanceState);
   mIsCreated = true;
   if (!mCalled) {
       throw new SuperNotCalledException("Fragment " + this
               + " did not call through to super.onCreate()");
   }
   // 发射 lifecycle 事件,更新 lifecycle 状态
   mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}

void performDestroy() {
   mChildFragmentManager.dispatchDestroy();
   // 发射 lifecycle 事件,更新 lifecycle 状态
   mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
   mState = ATTACHED;
   mCalled = false;
   mIsCreated = false;
   // 生命周期回调
   onDestroy();
   if (!mCalled) {
       throw new SuperNotCalledException("Fragment " + this
               + " did not call through to super.onDestroy()");
   }
}
  • 还有个值得注意的地方就是对 Event.ON_STOP 的处理。在上面的调用图中我们可以看到,在 onSaveInstanceStateonStop 时都派发了 Event.ON_STOP 事件,且将状态置为了 CREATED。这是因为,在 onSaveInstanceState 后,其实不应该再更新界面了,此时就先派发 Event.ON_STOP 使其状态为 CREATED,阻止 ViewModel 更新 UI。同时 onStop 时也需要派发,因为当 Activity 销毁时,不一定调用 onSaveInstanceState
2. LifecycleRegistry

LifecycleRegistryLifecycle 的唯一实现类,负责管理 LifecycleOwner 的当前状态,及接收 Lifecycle 事件后状态的流转,负责添加移除观察者 LifecycleObserver,并向观察者通知 LifecycleOwner 当前的状态。主要实现了以下的逻辑:

  • addObserver 添加观察者时,当前的 LifecycleOwner 处于什么状态,观察者将一次性收到这个状态前的所有事件。比如,在 onPause 时调用 addObserver,由于此时 LifecyclerOwner(也就是 Activity) 处于 STARTED 状态,因此观察者将一次性依次收到 ON_CREATEON_START 两个事件。

  • 我们在实现观察者时,使用了 @OnLifecycleEvent 注解向 LifecycleRegistery 表示我们关心的事件。其实 LifecycleRegistry 还为我们每个观察者绑定了状态以确保一种有序性:在任意时刻,后添加的观察者状态 <= 先添加的观察者状态。也就是,先添加的观察者会先收到最新状态。当然,最终的稳态一定是所有观察者的状态都一致,但是在给每个观察者派发事件的过程中,可能会出现各个观察者状态不一致的情况,LifecycleRegistry 会保证上面所说的有序性。

2.1 LifecycleRegistry 的 handleLifecycleEvent 方法 & markState() 方法

看下 handleLifecycleEvent 的源码:

public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    State next = getStateAfter(event);
    moveToState(next);
}

// markState 被 @Deprecated 了,使用 setCurrentState
public void setCurrentState(@NonNull State state) {
    moveToState(state);
}

可以看到,handleLifecycleRegistry 只是多了一步 getStateAfter 方法,根据 (1),这个方法只是根据一个固定的「事件 —— 状态」流转表来获取当前应该传入给 moveToState 的状态值。

由于 ActivityFragment 有固定的「事件 —— 状态」流转表,因此在 ActivityFragment 的生命周期方法中,源码使用 handleLifecycleRegistry()。但是当我们自定义了一个 LifecycleOwner 的时候,可能「事件 —— 状态」并不需要那么齐全,这时我们只需要在合适的方法中调用 markState() 就可以了。

二、LifecycleOwner

LifecycleOwner 是一个接口,只有唯一的方法 getLifecycle()。它的典型使用方法就是,一个具有生命周期的类,实现该接口,返回该类对应的 Lifecycle 类(最好用现成的 LifecycleRegistry)。然后在该类(比如 ActivityFragment)的生命周期方法中,调用的 LifecycleRegistry.handleLifecycleEvent 方法,来驱动 Lifecycle 状态的改变,同时下发相应事件。在正常的实践中,LifecycleOwner 是跟 LifecycleRegistry 一起使用的:

class MyActivity : Activity(), LifecycleOwner {

    private lateinit var lifecycleRegistry: LifecycleRegistry

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        lifecycleRegistry = LifecycleRegistry(this)
        lifecycleRegistry.markState(Lifecycle.State.CREATED)
    }

    public override fun onStart() {
        super.onStart()
        lifecycleRegistry.markState(Lifecycle.State.STARTED)
    }

    override fun getLifecycle(): Lifecycle {
        return lifecycleRegistry
    }
}

三、生命周期事件如何在 Activity 和 Fragment 中分发的?

上一节我们说到,生命周期事件的分发是 LifecycleOwnerLifecycleRegistry 配合一起的作用,我们来看看常用的 AppCompatActivity。它继承自 FragmentActivity,在这个类里我们就发现了下面的代码:

/**
 * A {@link Lifecycle} that is exactly nested outside of when the FragmentController
 * has its state changed, providing the proper nesting of Lifecycle callbacks
 * 

* TODO(b/127528777) Drive Fragment Lifecycle with LifecycleObserver */ final LifecycleRegistry mFragmentLifecycleRegistry = new LifecycleRegistry(this);

不要误以为 mFragmentLifecycleRegistry 就是 Activity 所对应的 LifecycleRegistry。它虽然在 Activity 的各个生命周期方法中都有调用 handleLifecycleEvent 方法,但是真正使用它的地方是 FragmentActivity 的内部类 HostCallbacks 中。

mFragmentLifecycleRegistry

HostCallbacks 的实例作为参数传入了 FragmentController 中:

final FragmentController mFragments = FragmentController.createController(new HostCallbacks());

这里的 mFragments 其实就是一个代理(可以看 ViewModel 的重建恢复原理#番外),它将 Fragment 所关心的 Activity 的事件等通知给 HostCallbacks 所持有的 FragmentManager,包括 Activity 的生命周期。这样 Activity 的生命周期就传给了 Fragment

所以 mFragmentLifecycleRegistry 只是 Activity 将生命周期事件通知给 Fragment 的桥梁。

FragmentActivity 真正的 LifecycleRegistry 应该是通过 getLifecycle() 方法所返回的。jojo

Q: 但是并没有传给 Activity 作为 LifecycleOwner 所对应的 LifecycleRegistry。那么 ActivityLifecycleRegistry 是在哪里呢?

我们再往父类看 ComponentActivity。在这里我们找到了:

private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    ReportFragment.injectIfNeededIn(this);
    ...
}

关键点就在这个 ReportFragment。我们注意到 ReportFragment.dispatch 中获取到了 ActivityLifecycle,并调用了 dispatchLifecycleEvent 方法从而将生命周期事件通知到了 ActivityLifecycle

// ReportFragment
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
    if (activity instanceof LifecycleRegistryOwner) {
        ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
        return;
    }
    if (activity instanceof LifecycleOwner) {
        Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
        if (lifecycle instanceof LifecycleRegistry) {
            ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
        }
    }
}

我们再看 ReportFragment.injectIfNeededIn 方法:

public static void injectIfNeededIn(Activity activity) {
    if (Build.VERSION.SDK_INT >= 29) {
        // On API 29+, we can register for the correct Lifecycle callbacks directly
        activity.registerActivityLifecycleCallbacks(
                new LifecycleCallbacks());
    }
    // Prior to API 29 and to maintain compatibility with older versions of
    // ProcessLifecycleOwner (which may not be updated when lifecycle-runtime is updated and
    // need to support activities that don't extend from FragmentActivity from support lib),
    // use a framework fragment to get the correct timing of Lifecycle events
    android.app.FragmentManager manager = activity.getFragmentManager();
    if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
        manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
        // Hopefully, we are the first to make a transaction.
        manager.executePendingTransactions();
    }
}

可以注意到:

  • 对于 SDK API ≥ 29 的系统,通过直接向 Activity 注册 LifecycleCallbacks 回调来将生命周期事件通知给 LifecycleRegistryLifecycleCallbacks 中的每一个回调都会调用上面的 dispatch 方法。
  • 对于 SDK API < 29 的系统,则将该 ReportFragment 添加到 ActivityFragmentManager 中。这样就可以在 ReportFragment 自己的生命周期回调中调用 dispatch 方法。

四、我们使用注解的 Observer 是如何收到生命周期事件的?

注解生成的类

要理解这一节的内容,最好能够理解注解处理器的使用。我们知道 APT 在扫描被注解的类后,会调用相应的 processor 来处理这个类,如果有必要,可能会根据这个类的信息来生成一个新的中间类。这个新的中间类就会有很多模板写法(因此才能够被生成)。我们来看一个使用注解的类:

static class BoundLocationListener implements LifecycleObserver {
    private final Context mContext;
    private LocationManager mLocationManager;
    private final LocationListener mListener;
    public BoundLocationListener(LifecycleOwner lifecycleOwner,
                                 LocationListener listener, Context context) {
        mContext = context;
        mListener = listener;
        lifecycleOwner.getLifecycle().addObserver(this);
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    void onLifecycleEvent(LifecycleOwner owner, Lifecycle.Event event) {
        Log.d("jojo", "onLifecycleEvent " + owner.getLifecycle().getCurrentState() + ", event " + event);
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    void addLocationListener() {
        // Note: Use the Fused Location Provider from Google Play Services instead.
        // https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderApi
        mLocationManager =
                (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
        mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mListener);
        Log.d("BoundLocationMgr", "Listener added");
        // Force an update with the last location, if available.
        Location lastLocation = mLocationManager.getLastKnownLocation(
                LocationManager.GPS_PROVIDER);
        if (lastLocation != null) {
            mListener.onLocationChanged(lastLocation);
        }
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    void removeLocationListener() {
        if (mLocationManager == null) {
            return;
        }
        mLocationManager.removeUpdates(mListener);
        mLocationManager = null;
        Log.d("BoundLocationMgr", "Listener removed");
    }
}

上面的 BoundLocationListener 类抛开业务逻辑代码,其实非常简单:它继承自 LifecycleObserver,其中的两个方法 addLocationListenerremoveLocationListener 分别被 @OnLifecycleEvent 注解了不同的生命周期。
我们再来看看 BoundLocationListenerprocessor 处理后所生成的中间类:

public class BoundLocationManager_BoundLocationListener_LifecycleAdapter implements GeneratedAdapter {
  final BoundLocationManager.BoundLocationListener mReceiver;
  BoundLocationManager_BoundLocationListener_LifecycleAdapter(BoundLocationManager.BoundLocationListener receiver) {
    this.mReceiver = receiver;
  }
  @Override
  public void callMethods(LifecycleOwner owner, Lifecycle.Event event, boolean onAny,
      MethodCallsLogger logger) {
    boolean hasLogger = logger != null;
    if (onAny) {
      if (!hasLogger || logger.approveCall("onLifecycleEvent", 4)) {
        mReceiver.onLifecycleEvent(owner,event);
      }
      return;
    }
    if (event == Lifecycle.Event.ON_RESUME) {
      if (!hasLogger || logger.approveCall("addLocationListener", 1)) {
        mReceiver.addLocationListener();
      }
      return;
    }
    if (event == Lifecycle.Event.ON_PAUSE) {
      if (!hasLogger || logger.approveCall("removeLocationListener", 1)) {
        mReceiver.removeLocationListener();
      }
      return;
    }
  }
}
  • 首先从类名上就看得出是由模板拼接出来的,这是方便我们后面说的 Lifecycling 通过反射找到该类。
  • 它实现了一个统一的接口 GeneratedAdapter,其中只有一个方法 callMethods。统一的接口方便 Lifecycling 统一的管理,因为对于 Lifecycling 来说,这些生成类都是 GeneratedAdapter 而已。
  • 该类持有 BoundLocationListener 的实例,并且在 callMethods 方法中,通过条件判断生命周期事件来调用 BoundLocationListener 的不同方法。
管理注解生成类

分析完注解中间产物类,我们有一个疑问:它是在哪里被初始化,又是在哪里被管理的呢?
我们来看 Observer 被加载到哪里去了。我们知道添加观察者、移除观察者的地方是在 LifecycleRegistry 里,在 addObserver 方法中,将传入进来的 LifecycleObserver 包装成了 ObserverWithState。我们来看看 ObserverWithState

static class ObserverWithState {
    State mState;
    LifecycleEventObserver mLifecycleObserver;
    ObserverWithState(LifecycleObserver observer, State initialState) {
        // 这里将 observer 又包装了一遍
        mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
        mState = initialState;
    }
    void dispatchEvent(LifecycleOwner owner, Event event) {
        State newState = getStateAfter(event);
        mState = min(mState, newState);
        mLifecycleObserver.onStateChanged(owner, event);
        mState = newState;
    }
}

Lifecycling 类是我们写注解时常使用的那种中间 Helper 类,一般来说,它会通过反射等手段来找到我们前面所说的中间产物类(例子中的 BoundLocationManager_BoundLocationListener_LifecycleAdapter 类),管理它的实例、生命周期、方法调用等,并将被注解的业务类与中间产物类绑定起来。
Lifecycling 的代码逻辑就比较多了,而且都是用的 Java 反射的特性,我们就不再详细讲解。只说说 lifecycleEventObserver 方法。它会根据我们传入的 observerClass,然后根据 APT processor 中一样的规则来生成中间产物类的类名,然后通过反射得到类的构造函数 Constructor 类,并将其存入到缓存中(方便下次使用时不再反射去找)。最后调用该构造函数,在本例中就是调用 BoundLocationManager_BoundLocationListener_LifecycleAdapter(BoundLocationManager.BoundLocationListener receiver),并返回。返回后就是 ObserverWithState.mLifecycleObserver。当 LifecycleRegistry 分发事件时,最后会调用到 ObserverWithState.dispatchEvent -> mLifecycleObserver.onStateChanged -> ... -> BoundLocationManager_BoundLocationListener_LifecycleAdapter.callMethods

LiveData

我们知道 LiveData 也是具有生命周期感知能力的,它与 Lifecycle 绑定,只有当生命周期为 STARTEDRESUMED 时,它才会向观察者发射数据。同时,在生命周期为 DESTROYED 时,LiveData 也能够自己释放。
要实现上面的能力,LiveData需要自己既是数据的发射者,又是生命周期事件的观察者。数据观察者通过 observe(LifecycleOwner, Observer) 方法来将自己与 LiveData 绑定,同时为 LiveData 注入 LifecycleOwner,这样就使 LiveData 观察生命周期事件成为了可能。

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
    assertMainThread("observe");
    // 如果 Lifecycle 处于 DESTROYED 状态,那么就不会往观察者发射数据
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        // ignore
        return;
    }
    // 将 owner 和 observer 一起封装为 LifecycleBoundObserver。
    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;
    }
    // 将 LifecycleBoundObserver 作为观察者添加进 Lifecycle。
    // 这样,当有生命周期事件时,会调用 LifecycleBoundObserver 的 onStateChange
    owner.getLifecycle().addObserver(wrapper);
}

从上面我们可以看到,LiveData 自身其实只是一个管理类。它通过操作 LifecycleBoundObserver 来将 LifecycleObserver 关联起来。我们来看下 LifecycleBoundObserver

class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
    @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(@NonNull LifecycleOwner source,
            @NonNull 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);
    }
}

对于 Lifecycle 来说,上面的类其实是 LifecycleEventObserver,当 Lifecycle 的生命周期事件需要下发时,它会调用 LifecycleEventObserver.onStateChanged,在这个方法中我们会看到,如果当前生命周期事件是 DESTROYED,那么会调用 removeObserver 将观察者从 Lifecycle 中移除掉。否则判断生命周期是否 ≥ STARTED,如果是的话,则将 LifecycleBoundObserver 的状态置为 active,并向开发者回调 onActive 方法,否则置为 inactive 状态,并向开发者回调 onInactive 方法。

LiveData 下发初值

LifecycleBoundObserver 变为 active 状态时,马上调用 dispatchingValue 下发当前值。因此 LiveData 的这个行为有点类比于 RxJavaBehaviorSubject这个技术实现的关键点在于 considerNotify 函数:

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;
    observer.mObserver.onChanged((T) mData);
}

上面的 observer.mLastVersion >= mVersion 决定了的一系列关键行为。mVersion 初值为 -1,在 LiveData 每次更新值后,mVersion 都会自增 1。

  • LiveData 中已经有值,此时有一个新的观察者 observer 订阅 LiveData。由于observer.mLastVersion 的初值为 -1,因此上面条件不成立,LiveData 向新观察者 observer 下发一次当前值。
  • 上面的情况还适合应用因配置改变而导致 ActivityFragment 重建。由于 LiveData 配合使用在 ViewModel 中,因此重建后 ActivityFragment 中的观察者对于 ViewModel 中的 LiveData 来说依然是新的观察者。
  • 如果观察者不被重建,则 LiveDatainactive 变为 active 时,且 LiveDatainactive 时更新过数据,上面条件不成立,观察者还是会收到 LiveData 最新的数据。反之,LiveDatainactive 时没有更新过数据,则观察者不会收到 LiveData 最近一次的数据。
LiveData 更新值

我们来看看 LiveData.setValue

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

实现上一小节中的关键点就在于 setValue 时,将 mVersion 自增 1 来更新版本号。

你可能感兴趣的:(Lifecycle 解惑)