注册

Android Jetpack系列之Lifecycle

Lifecycle介绍

Lifecycle可以让某一个类变成ActivityFragment的生命周期观察者类,监听其生命周期的变化并可以做出响应。Lifecycle使得代码更有条理性、精简、易于维护。

Lifecycle中主要有两个角色:

  • LifecycleOwner: 生命周期拥有者,如Activity/Fragment等类都实现了该接口并通过getLifecycle()获得Lifecycle,进而可通过addObserver()添加观察者。
  • LifecycleObserver: 生命周期观察者,实现该接口后就可以添加到Lifecycle中,从而在被观察者类生命周期发生改变时能马上收到通知。

实现LifecycleOwner的生命周期拥有者可与实现LifecycleObserver的观察者完美配合。

场景case

假设我们有一个在屏幕上显示设备位置的 Activity,我们可能会像下面这样实现:

internal class MyLocationListener(
private val context: Context,
private val callback: (Location) -> Unit) {

fun start() {
// connect to system location service
}

fun stop() {
// disconnect from system location service
}
}

class MyActivity : AppCompatActivity() {
private lateinit var myLocationListener: MyLocationListener

override fun onCreate(...) {
myLocationListener = MyLocationListener(this) { location ->
// update UI
}
}

public override fun onStart() {
super.onStart()
myLocationListener.start()
// manage other components that need to respond
// to the activity lifecycle
}

public override fun onStop() {
super.onStop()
myLocationListener.stop()
// manage other components that need to respond
// to the activity lifecycle
}
}

注:上面代码来自官方示例~

我们可以在Activity 或 Fragment 的生命周期方法(示例中的onStart/onStop)中直接对依赖组件进行操作。但是,这样会导致代码条理性很差且不易扩展。那么有了Lifecycle,可以将依赖组件的代码从Activity/Fragment生命周期方法中移入组件本身中。

Lifecycle使用

根目录下build.gradle:

allprojects {
repositories {
google()

// Gradle小于4.1时,使用下面的声明替换:
// maven {
// url 'https://maven.google.com'
// }
// An alternative URL is 'https://dl.google.com/dl/android/maven2/'
}
}

app下的build.gradle:

    dependencies {
def lifecycle_version = "2.3.1"
def arch_version = "2.1.0"

// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// Lifecycles only (without ViewModel or LiveData)
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"

// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"

// Annotation processor
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// 可选 - 如果使用Java8,使用下面这个代替lifecycle-compiler
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"

// 可选 - 在Service中使用Lifecycle
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"

// 可选 - Application中使用Lifecycle
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"

// 可选 - ReactiveStreams support for LiveData
implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"

// 可选 - Test helpers for LiveData
testImplementation "androidx.arch.core:core-testing:$arch_version"
}

Activity/Fragment中使用Lifecycle

首先先来实现LifecycleObserver观察者:

open class MyLifeCycleObserver : LifecycleObserver {

@OnLifecycleEvent(value = Lifecycle.Event.ON_START)
fun connect(owner: LifecycleOwner) {
Log.e(JConsts.LIFE_TAG, "Lifecycle.Event.ON_CREATE:connect")
}

@OnLifecycleEvent(value = Lifecycle.Event.ON_STOP)
fun disConnect() {
Log.e(JConsts.LIFE_TAG, "Lifecycle.Event.ON_DESTROY:disConnect")
}
}

在方法上,我们使用了@OnLifecycleEvent注解,并传入了一种生命周期事件,其类型可以为ON_CREATEON_STARTON_RESUMEON_PAUSEON_STOPON_DESTROYON_ANY中的一种。其中前6个对应Activity中对应生命周期的回调,最后一个ON_ANY可以匹配任何生命周期回调。 所以,上述代码中的connect()、disConnect()方法分别应该在ActivityonStart()、onStop()中触发时执行。接着来实现我们的Activity:

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onCreate")

//添加LifecycleObserver观察者
lifecycle.addObserver(MyLifeCycleObserver())
}

override fun onStart() {
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onStart")
super.onStart()
}

override fun onResume() {
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onResume")
super.onResume()
}

override fun onPause() {
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onPause")
super.onPause()
}

override fun onStop() {
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onStop")
super.onStop()
}

override fun onDestroy() {
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onDestroy")
super.onDestroy()
}
}

可以看到在Activity中我们只是在onCreate()中添加了这么一行代码:

lifecycle.addObserver(MyLifeCycleObserver())

其中getLifecycle()LifecycleOwner中的方法,返回的是Lifecycle对象,并通过addObserver()的方式添加了我们的生命周期观察者。接下来看执行结果,启动Activity:

2021-06-30 20:57:58.038 11257-11257/ E/Lifecycle_Study: ACTIVITY:onCreate

//onStart() 传递到 MyLifeCycleObserver: connect()
2021-06-30 20:57:58.048 11257-11257/ E/Lifecycle_Study: ACTIVITY:onStart
2021-06-30 20:57:58.049 11257-11257/ E/Lifecycle_Study: Lifecycle.Event.ON_START:connect

2021-06-30 20:57:58.057 11257-11257/ E/Lifecycle_Study: ACTIVITY:onResume

关闭Activity:

2021-06-30 20:58:02.646 11257-11257/ E/Lifecycle_Study: ACTIVITY:onPause

//onStop() 传递到 MyLifeCycleObserver: disConnect()
2021-06-30 20:58:03.149 11257-11257/ E/Lifecycle_Study: ACTIVITY:onStop
2021-06-30 20:58:03.161 11257-11257/ E/Lifecycle_Study: Lifecycle.Event.ON_STOP:disConnect

2021-06-30 20:58:03.169 11257-11257/ E/Lifecycle_Study: ACTIVITY:onDestroy

可以看到我们的MyLifeCycleObserver中的connect()/disconnect()方法的确是分别在ActivityonStart()/onStop()回调时执行的。

自定义LifecycleOwner

AndroidX中的Activity、Fragmen实现了LifecycleOwner,通过getLifecycle()能获取到Lifecycle实例(Lifecycle是抽象类,实例化的是子类LifecycleRegistry)。

public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}

public class LifecycleRegistry extends Lifecycle {

}

如果我们想让一个自定义类成为LifecycleOwner,可以直接实现LifecycleOwner

class CustomLifeCycleOwner : LifecycleOwner {
private lateinit var registry: LifecycleRegistry

fun init() {
registry = LifecycleRegistry(this)
//通过setCurrentState来完成生命周期的传递
registry.currentState = Lifecycle.State.CREATED
}

fun onStart() {
registry.currentState = Lifecycle.State.STARTED
}

fun onResume() {
registry.currentState = Lifecycle.State.RESUMED
}

fun onPause() {
registry.currentState = Lifecycle.State.STARTED
}

fun onStop() {
registry.currentState = Lifecycle.State.CREATED
}

fun onDestroy() {
registry.currentState = Lifecycle.State.DESTROYED
}

override fun getLifecycle(): Lifecycle {
//返回LifecycleRegistry实例
return registry
}
}

首先我们的自定义类实现了接口LifecycleOwner,并在getLifecycle()返回LifecycleRegistry实例,接下来就可以通过LifecycleRegistry#setCurrentState来传递生命周期状态了。到目前为止,已经完成了大部分工作,最后也是需要去添加LifecycleObserver:

可以看到getLifecycle()返回的是LifecycleRegistry实例,并且在onSaveInstanceState()中分发了Lifecycle.State.CREATED状态,但是其他生命周期回调中并没有写了呀,嗯哼?再细看一下,onCreate()中有个ReportFragment.injectIfNeededIn(this),直接进去看看:

ObserverWithState#dispatchEvent()中调用了mLifecycleObserver.onStateChanged(),这个mLifecycleObserverLifecycleEventObserver类型(父类是接口LifecycleObserver ),在构造方法中通过Lifecycling.lifecycleEventObserver()创建的,最终返回的是ReflectiveGenericLifecycleObserver

//ReflectiveGenericLifecycleObserver.java
class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
private final Object mWrapped;
private final CallbackInfo mInfo;

ReflectiveGenericLifecycleObserver(Object wrapped) {
mWrapped = wrapped;
mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
}

@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Event event) {
mInfo.invokeCallbacks(source, event, mWrapped);
}
}

ClassesInfoCache内部存了所有观察者的回调信息,CallbackInfo是当前观察者的回调信息。getInfo()中如果从内存mCallbackMap中有对应回调信息,直接返回;否则通过createInfo()内部解析注解OnLifecycleEvent对应的方法并最终生成CallbackInfo返回。

//ClassesInfoCache.java
CallbackInfo getInfo(Class<?> klass) {

CallbackInfo existing = mCallbackMap.get(klass);
if (existing != null) {
return existing;
}
existing = createInfo(klass, null);
return existing;
}

private void verifyAndPutHandler(Map<MethodReference, Lifecycle.Event> handlers,
MethodReference newHandler, Lifecycle.Event newEvent, Class<?> klass) {
Lifecycle.Event event = handlers.get(newHandler);
if (event == null) {
handlers.put(newHandler, newEvent);
}
}

private CallbackInfo createInfo(Class<?> klass, @Nullable Method[] declaredMethods) {
Class<?> superclass = klass.getSuperclass();
Map<MethodReference, Lifecycle.Event> handlerToEvent = new HashMap<>();
if (superclass != null) {
CallbackInfo superInfo = getInfo(superclass);
if (superInfo != null) {
handlerToEvent.putAll(superInfo.mHandlerToEvent);
}
}

Class<?>[] interfaces = klass.getInterfaces();
for (Class<?> intrfc : interfaces) {
for (Map.Entry<MethodReference, Lifecycle.Event> entry : getInfo(
intrfc).mHandlerToEvent.entrySet()) {
verifyAndPutHandler(handlerToEvent, entry.getKey(), entry.getValue(), klass);
}
}

Method[] methods = declaredMethods != null ? declaredMethods : getDeclaredMethods(klass);
boolean hasLifecycleMethods = false;
//遍历寻找OnLifecycleEvent注解对应的方法
for (Method method : methods) {
OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
if (annotation == null) {
continue;
}
hasLifecycleMethods = true;
Class<?>[] params = method.getParameterTypes();
int callType = CALL_TYPE_NO_ARG;
if (params.length > 0) {
callType = CALL_TYPE_PROVIDER;
//第一个方法参数必须是LifecycleOwner
if (!params[0].isAssignableFrom(LifecycleOwner.class)) {
throw new IllegalArgumentException(
"invalid parameter type. Must be one and instanceof LifecycleOwner");
}
}
Lifecycle.Event event = annotation.value();

if (params.length > 1) {
callType = CALL_TYPE_PROVIDER_WITH_EVENT;
//第2个参数必须是Lifecycle.Event
if (!params[1].isAssignableFrom(Lifecycle.Event.class)) {
throw new IllegalArgumentException(
"invalid parameter type. second arg must be an event");
}
//当有2个参数时,注解必须是Lifecycle.Event.ON_ANY
if (event != Lifecycle.Event.ON_ANY) {
throw new IllegalArgumentException(
"Second arg is supported only for ON_ANY value");
}
}
if (params.length > 2) {
throw new IllegalArgumentException("cannot have more than 2 params");
}
MethodReference methodReference = new MethodReference(callType, method);
verifyAndPutHandler(handlerToEvent, methodReference, event, klass);
}
CallbackInfo info = new CallbackInfo(handlerToEvent);
mCallbackMap.put(klass, info);
mHasLifecycleMethods.put(klass, hasLifecycleMethods);
return info;
}

//CallbackInfo.java
static class CallbackInfo {
final Map<Lifecycle.Event, List<MethodReference>> mEventToHandlers;
final Map<MethodReference, Lifecycle.Event> mHandlerToEvent;

CallbackInfo(Map<MethodReference, Lifecycle.Event> handlerToEvent) {
mHandlerToEvent = handlerToEvent;
mEventToHandlers = new HashMap<>();
for (Map.Entry<MethodReference, Lifecycle.Event> entry : handlerToEvent.entrySet()) {
Lifecycle.Event event = entry.getValue();
List<MethodReference> methodReferences = mEventToHandlers.get(event);
if (methodReferences == null) {
methodReferences = new ArrayList<>();
mEventToHandlers.put(event, methodReferences);
}
methodReferences.add(entry.getKey());
}
}

void invokeCallbacks(LifecycleOwner source, Lifecycle.Event event, Object target) {
invokeMethodsForEvent(mEventToHandlers.get(event), source, event, target);
invokeMethodsForEvent(mEventToHandlers.get(Lifecycle.Event.ON_ANY), source, event,
target);
}

private static void invokeMethodsForEvent(List<MethodReference> handlers,
LifecycleOwner source, Lifecycle.Event event, Object mWrapped) {
if (handlers != null) {
for (int i = handlers.size() - 1; i >= 0; i--) {
handlers.get(i).invokeCallback(source, event, mWrapped);
}
}
}

最终调用到了MethodReference#invokeCallback()

//MethodReference.java
static class MethodReference {
final int mCallType;
final Method mMethod;

MethodReference(int callType, Method method) {
mCallType = callType;
mMethod = method;
mMethod.setAccessible(true);
}

void invokeCallback(LifecycleOwner source, Lifecycle.Event event, Object target) {
//noinspection TryWithIdenticalCatches
try {
//OnLifecycleEvent注解对应的方法入参
switch (mCallType) {
//没有参数
case CALL_TYPE_NO_ARG:
mMethod.invoke(target);
break;
//一个参数:LifecycleOwner
case CALL_TYPE_PROVIDER:
mMethod.invoke(target, source);
break;
//两个参数:LifecycleOwner,Event
case CALL_TYPE_PROVIDER_WITH_EVENT:
mMethod.invoke(target, source, event);
break;
}
} catch (InvocationTargetException e) {
throw new RuntimeException("Failed to call observer method", e.getCause());
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}

MethodReference that = (MethodReference) o;
return mCallType == that.mCallType && mMethod.getName().equals(that.mMethod.getName());
}

@Override
public int hashCode() {
return 31 * mCallType + mMethod.getName().hashCode();
}
}

根据不同入参个数通过反射来初始化并执行观察者相应方法,整个流程就从LifecycleOwner中的生命周期Event传到了LifecycleObserver中对应的方法。到这里整个流程就差不多结束了,最后是LifecycleOwner的子类LifecycleRegistry添加观察者的过程:

//LifecycleRegistry.java
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
//key是LifecycleObserver,value是ObserverWithState
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
//如果已经存在,直接返回
if (previous != null) {
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}

boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
//目标State
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
//循环遍历,将目标State连续同步到Observer中
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}

if (!isReentrance) {
// we do sync only on the top level.
sync();
}
mAddingObserverCounter--;
}

private State calculateTargetState(LifecycleObserver observer) {
Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);

State siblingState = previous != null ? previous.getValue().mState : null;
State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
: null;
return min(min(mState, siblingState), parentState);
}

添加观察者,并通过while循环,将最新的State状态连续同步到Observer中,虽然可能添加ObserverLifecyleOwner分发事件晚,但是依然能收到所有事件,类似于事件总线的粘性事件。最后画一下整体的类图关系: Lifecycle.png


0 个评论

要回复文章请先登录注册