android Lifecycles 的三种用法和原理

8,067 阅读6分钟

作用

在这里我们将与 Lifecycles 相关的组件称为 Lifecycle-aware components(生命周期感知组件),这里它感知的一般是 Activity 和 Fragment 的生命周期,它设计的目的就是用来管理 Activity 和 Fragment 的生命周期,以减少内存泄露甚至崩溃的异常问题的出现。

在没有 Lifecycles 之前,如果一些组件需要感知 Activity 的生命周期必须显示的在 Activity 的生命周期方法中调用,有时候代码太多会造成代码阅读性差,耦合性高,本着分离的原则谷歌设计了 Lifecycles 的相关组件。

设计思想

Lifecycles 采用观察者模式:

  • LifecycleOwner:被观察者,Activity 和 Fragment 都实现了此接口;
  • LifecycleObserver:观察者,我们自己实现的业务组件需要继承此类;
  • Lifecycle:用于存储有关组件(如 Activity 或 Fragment)的生命周期状态的信息,并允许其他对象观察此状态,包含增删观察者,获取被观察者的状态。 三者的关系如下:

简单用法

1. 定义一个观察者 - 实现 LifecycleObserver

LocationPresenter,它实现了 LifecycleObserver

class LocationPresenter : LifecycleObserver {
    private val tag = LocationPresenter::class.java.simpleName
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun onResume() {
        Log.i(tag, "onResume")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun onPause() {
        Log.i(tag, "onPause")
    }
}

为了让被观察者识别我们写的 onResume 方法需要在被观察者 onResume 时调用,我们需要添加注解 @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) ,这里的原理下面再分析。

2. 定义被观察者 - 实现 LifecycleOwner

Support Library 26.1.0 及更高版本中的 Fragment 和 Activity 已实现 LifecycleOwner 接口。 rce/p97

这里使用的是lib 是 androidx。 这样我们就可以在 Activity 中通过 getLifcycle 方法获取 Lifcycle 进行注册了:

class JetpackMainActivity : AppCompatActivity() {
    private lateinit var locationPresenter: LocationPresenter
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.jk_activity_jetpack_main)
        locationPresenter = LocationPresenter()

        lifecycle.addObserver(locationPresenter)
    }
}

使用就是这么简单。

3.低版本下实现 LifecycleOwner

低版本下我们需要 new 一个 LifecycleRegistry, 它是 LifeCycle 的子类,然后在生命周期变化时调用 LifecycleRegistry 的 markState 方法。

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

原理解析

网上分析 Lifecycles 源码的文章有很多,这里就不逐个分析 Lifecycles 的源码了,主要挑笔者认为最重要的两个来分析一下。

事件的分发

Fragment 的事件分发

我们先以 Fragment 为例,Fragment 实现了 LifecycleOwner 接口:

public class Fragment implements LifecycleOwner {
    LifecycleRegistry mLifecycleRegistry;
    public Fragment() {
        initLifecycle();
    }
    private void initLifecycle() {
        mLifecycleRegistry = new LifecycleRegistry(this);
        ...
    }
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
    ...
    
    void performCreate(Bundle savedInstanceState) {
       ...
       mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
    }
    
    void performStart() {
        ...
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    }

    void performResume() {
       ... 
       mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    }
    ...
}

Fragment 在初始化的时候实例化了一个 Lifecycle 的子类 - LifecycleRegistry,我们通过 getLifecycle 就可以获得 LifecycleRegistry 来添加观察者。

然后 Fragment 中按照生命周期定义了一系列的 perform 方法,比如 performCreate,performStart 等。 每当生命周期走到 onStart 的时候就会调用 performStart 方法(实际是 FragmentManagerImpl 中的 moveToState 方法调用的),进而调用 LifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START) 来通知观察者,LifecycleRegistry 的 handleLifecycleEvent 方法如下:

public class LifecycleRegistry extends Lifecycle {
    private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>();
    private State mState;
    private final WeakReference<LifecycleOwner> mLifecycleOwner;
    
    public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        State next = getStateAfter(event);
        moveToState(next);
    }
    
    private void moveToState(State next) {
       ...
        sync();
       ...
    }
    private void sync() {
        LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
        ...
        while (!isSynced()) {
           ...
            if (!mNewEventOccurred && newest != null
                    && mState.compareTo(newest.getValue().mState) > 0) {
                forwardPass(lifecycleOwner);
            }
        ...
    }
    private void forwardPass(LifecycleOwner lifecycleOwner) {
        ...
            ObserverWithState observer = entry.getValue();
            ...
                observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
            ...
        ...
}

可以看到最终的分发操作由 ObserverWithState 执行,它回调了 LifeObserver 的 onStateChange 回调:

static class ObserverWithState {
        State mState;
        LifecycleEventObserver mLifecycleObserver;

        ObserverWithState(LifecycleObserver observer, State initialState) {
            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;
        }
    }

看到 mLifecycleObserver.onStateChanged(owner, event) 这行代码可能会疑惑:我们在使用的时候并没有写过 onStateChanged 方法啊,这个在后面会将。

Activity 的事件分发

Activity 中的生命周期通知是通过 ReportFragment 来实现的,首先在 Activity 的方法中注册了一个 ReportFragment:

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        LifecycleOwner,
        ViewModelStoreOwner,
        SavedStateRegistryOwner,
        OnBackPressedDispatcherOwner {
        @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        ReportFragment.injectIfNeededIn(this);
        ...
    }
  }

ReportFragment 比较简单,就是在生命周期方法中分发了相应的事件,以 onCreate 为例:

public class ReportFragment extends Fragment {
   
    public static void injectIfNeededIn(Activity activity) {
        android.app.FragmentManager manager = activity.getFragmentManager();
        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
            manager.executePendingTransactions();
        }
    }

    private void dispatchCreate(ActivityInitializationListener listener) {
        if (listener != null) {
            listener.onCreate();
        }
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        ...
        dispatch(Lifecycle.Event.ON_CREATE);
    }

    private void dispatch(Lifecycle.Event event) {
        Activity activity = getActivity();
        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);
            }
        }
    }

    ...
}

LifecycleObserver 的三种写法

我们在 addObserver 的时候,会经过下面的方法:

public class Lifecycling {
    
    @NonNull
    static LifecycleEventObserver lifecycleEventObserver(Object object) {
        boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;
        boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;
        // 观察者是 FullLifecycleObserver
        if (isLifecycleEventObserver && isFullLifecycleObserver) {
            return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,
                    (LifecycleEventObserver) object);
        }

        // 观察者是 LifecycleEventObserver
        if (isFullLifecycleObserver) {
            return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);
        }

        if (isLifecycleEventObserver) {
            return (LifecycleEventObserver) object;
        }

        final Class<?> klass = object.getClass();
        int type = getObserverConstructorType(klass);

        // 观察者是通过 apt 产生的类
        if (type == GENERATED_CALLBACK) {
            List<Constructor<? extends GeneratedAdapter>> constructors =
                    sClassToAdapters.get(klass);
            if (constructors.size() == 1) {
                GeneratedAdapter generatedAdapter = createGeneratedAdapter(
                        constructors.get(0), object);
                return new SingleGeneratedAdapterObserver(generatedAdapter);
            }
            GeneratedAdapter[] adapters = new GeneratedAdapter[constructors.size()];
            for (int i = 0; i < constructors.size(); i++) {
                adapters[i] = createGeneratedAdapter(constructors.get(i), object);
            }
            return new CompositeGeneratedAdaptersObserver(adapters);
        }
        
        // 观察者需要通过反射生成一个wrapper
        return new ReflectiveGenericLifecycleObserver(object);
    }

    ...

    public static String getAdapterName(String className) {
        return className.replace(".", "_") + "_LifecycleAdapter";
    }
}
FullLifecycleObserver
interface FullLifecycleObserver extends LifecycleObserver {

    void onCreate(LifecycleOwner owner);

    void onStart(LifecycleOwner owner);

    void onResume(LifecycleOwner owner);

    void onPause(LifecycleOwner owner);

    void onStop(LifecycleOwner owner);

    void onDestroy(LifecycleOwner owner);
}

这个接口需要实现所有的方法,这样会产生额外的无用代码。

LifecycleEventObserver
public interface LifecycleEventObserver extends LifecycleObserver {
    void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}

实现这个接口需要在 onStateChanged 判断一下状态,然后做相应的处理。

LifecycleObserver(使用注解标记方法)

使用注解的好处在于代码简洁清晰,我们需要监听哪一个生命周期事件就声明哪一个注解:

class LocationPresenter : LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun onResume() {
    }
}

上面再讲 Fragment 的时间分发的时候,可以看到,在 onResume 的时候,Fragment 调用的是 onStateChanged 方法,那么这个方法是如何生成的呢?这分为两种情况:

runtime 时期使用反射生成一个 wrapper
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(LifecycleOwner source, Event event) {
        mInfo.invokeCallbacks(source, event, mWrapped);
    }
}
编译时期使用 apt 生成 className + _LifecycleAdapter 类

使用 apt 时,我们需要在 gradle 中添加 compiler 依赖,如下:

dependencies {
    // java 写法
    annotationProcessor "androidx.lifecycle:lifecycle-compiler:2.1.0"
    // kotlin 写法
    kapt "androidx.lifecycle:lifecycle-compiler:2.1.0"
}

这样在编译器就会根据观察者的类名在加上后缀 _LifecycleAdapter 生成一个类,比如我们最开始写的 LocationPresenter 类,它会在下面的目录中生成一个类:

apt 会根据我们加的注解生成对应的逻辑,比如我们加了 onResume 和 onPause 的注解,生成的代码如下:

public class LocationPresenter_LifecycleAdapter implements GeneratedAdapter {
  final LocationPresenter mReceiver;

  LocationPresenter_LifecycleAdapter(LocationPresenter receiver) {
    this.mReceiver = receiver;
  }

  @Override
  public void callMethods(LifecycleOwner owner, Lifecycle.Event event, boolean onAny,
      MethodCallsLogger logger) {
    boolean hasLogger = logger != null;
    if (onAny) {
      return;
    }
    if (event == Lifecycle.Event.ON_RESUME) {
      if (!hasLogger || logger.approveCall("onResume", 1)) {
        mReceiver.onResume();
      }
      return;
    }
    if (event == Lifecycle.Event.ON_PAUSE) {
      if (!hasLogger || logger.approveCall("onPause", 1)) {
        mReceiver.onPause();
      }
      return;
    }
  }
}

如果你对 apt 不太了解可以参考我写的这篇文章: Android 注解(Annotation)的自定义和解析方式