文章目录

    • 前言
    • Lifecycles 体系
      • Lifecycle
      • LifecycleOwner
      • LifecycleObserver
    • 源码分析
      • Activity 实现 LifecycleOwner
      • Fragment 实现 LifecycleOwner
      • 小结

前言

Android架构组件(Android Architecture Components,简称AAC),是 Android Jetpack的一部分。Jetpack是谷歌的一整套开发库,具体包括下图中的内容:

谷歌对于AAC的介绍是:

Android architecture components are a collection of libraries that help you design robust, testable, and maintainable apps. Start with classes for managing your UI component lifecycle and handling data persistence.

具体而言:

  • Lifecycles: 用于更好的管理activity和fragment的生命周期。
  • LiveData:用于构建响应式的可感知生命周期的数据流。
  • ViewModel:用于独立于Android组件生命周期存储 UI 相关的数据。

此外AAC还包括其他的(比如Room)的很好用的库,但是我最感兴趣的就是这三个框架,因为LiveData提供了响应式框架(之前对响应式编程感兴趣而学习了一会儿RxJava,但是被复杂的API给劝退了,相较之下LiveData就很纯粹,搭建了响应式的架子,但没有Rx眼花缭乱的操作符);ViewModel看起来也解决了我一直以来在Android组件之间传递数据的痛点,而Lifecycles给LiveData提供了感知生命周期的能力。

以下所有源码基于androidx.lifecycle库,库的版本为2.1.0;androidx.appcompat库,库的版本为1.1.0

Lifecycles 体系

Lifecycles提供了一种通过订阅者模式来监听Activity和Fragment的生命周期变化的方式。之前,我们解决这种需求的方法是在Activity和Fragment的生命周期方法 onXX 系列方法中直接嵌入功能代码或调用回调,现在通过Lifecycles来实现监听可以有效减少耦合,隔离功能代码。
Lifecycles框架中包括三个角色: LifecycleLifecycleOwnerLifecycleObserver,其中Lifecycle包含有关组件(例如Activity或Fragment)生命周期状态的信息,并允许其他对象观察此状态;LifecycleOwner表示一个拥有Lifecycle的类,LifecycleObserver则是LifecycleOwner的生命周期状态的监听者。

Lifecycle

Lifecycle使用两个枚举StateEvent来表示其相关组件的状态和导致状态变化的事件,State包括5个值:DESTROYEDINITIALIZEDCREATEDSTARTEDRESUMEDEvent包括7个值:ON_CREATEON_STARTON_RESUMEON_PAUSEON_STOPON_DESTROYON_ANY,它们的关系如图:

这个图里没有ON_ANY,这是因为ON_ANY代表发生了“任一事件”,而不是特定的一种事件。可以看到Event对应了Activity和Fragment的生命周期方法。每两个相邻状态之间的转换只有一种特定事件。每个事件也只会在两种特定状态之间发生,因此可以把它们视作一个有向图,每个State是一个节点,而每个Event则是一条边。
Lifecycle的接口如下:

public abstract class Lifecycle {@MainThread    public abstract void addObserver(@NonNull LifecycleObserver observer);        @MainThread    public abstract void removeObserver(@NonNull LifecycleObserver observer);        @MainThread    public abstract State getCurrentState();}

Lifecycle 声明了三个方法:分别用来注册、反注册订阅者,以及获取当前所处状态。这三个方法都加了@MainThread注解(表示该方法只应该在主线程中调用),因此可以猜测,Lifecycle不是线程安全的。

LifecycleOwner

LifecycleOwner 的接口如下:

public interface LifecycleOwner {    Lifecycle getLifecycle();}

很简单,就只有一个给LifecycleObserver获取Lifecycle的接口。

LifecycleObserver

LifecycleObserver的接口如下:

public interface LifecycleObserver {}@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface OnLifecycleEvent {    Lifecycle.Event value();}

这是一个空接口,因为接受订阅事件的方法是需要通过OnLifecycleEvent注解添加,比如这样,onCreate方法会在ON_CREATE事件发生后调用:

 public static class TestObserver implements LifecycleObserver {         @OnLifecycleEvent(Event.ON_CREATE)        public void onCreate(LifecycleOwner owner) {            Log.d(TAG, "onCreate:  " + owner.getLifecycle().getCurrentState());        }}

LifecycleObserver还有几个子类

public interface LifecycleEventObserver extends LifecycleObserver {    void onStateChanged(LifecycleOwner source, Lifecycle.Event event);}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);}public interface DefaultLifecycleObserver extends FullLifecycleObserver {    default void onCreate(LifecycleOwner owner) { }    default void onStart(LifecycleOwner owner) { }    default void onResume(LifecycleOwner owner) { }    default void onPause(LifecycleOwner owner) { }    default void onStop(LifecycleOwner owner) { }    default void onDestroy(LifecycleOwner owner) { }}

创建LifecycleObserver一般可以通过直接继承LifecycleObserver或它的子类,但是使用DefaultLifecycleObserver需要使用Java1.8,因为它的实现用到了接口的default方法。

源码分析

Lifecycles 的接口以及看完了,接下来就来看它的实现,Lifecycles 的实现很明显是基于观察者模式的,并且观察者LifecycleObserver由我们自己实现,所以需要看的只由两部分:

  1. LifecycleOwner(实际上就是Android support库中的Activity和Fragment)是怎么发布事件和更新状态的。
  2. 注册和反注册,以及事件发布是如果管理的。

下面我就这两方面来看代码。

Activity 实现 LifecycleOwner

首先看Activity(androidx.appcompat.app.AppCompatActivity)的实现,LifecycleOwner接口的实现是在AppCompatActivity的父类ComponentActivity中,大概代码是下面这样(省略无关代码):

public class ComponentActivity  implements LifecycleOwner {private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);@Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        ReportFragment.injectIfNeededIn(this);    }    @Override    public Lifecycle getLifecycle() {        return mLifecycleRegistry;    }}

这里面我只保留了两个类:LifecycleRegistryReportFragment,它们是何许人也呢?
LifecycleRegistry的接口如下,

public class LifecycleRegistry extends Lifecycle {@MainThread    public void setCurrentState(@NonNull State state) {...}       public void handleLifecycleEvent(@NonNull Lifecycle.Event event){...}       @Override    public void addObserver(@NonNull LifecycleObserver observer){...}      @Override    public void removeObserver(@NonNull LifecycleObserver observer) {...}       public int getObserverCount() {...}        @Override    public State getCurrentState() {...}}

这个类的注释如下:

An implementation of Lifecycle that can handle multiple observers. It is used by Fragments and Support Library Activities. You can also directly use it if you have a custom LifecycleOwner.

由此可知,LifecycleRegistry就是我们要找的那个管理类,而ReportFragment,则是那个发布生命周期的类,ComponentActivity将发送事件的功能委托给了它。ReportFragment的方法大体如下:

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();     }}@Override    public void onStart() {        super.onStart();        dispatchStart(mProcessListener);        dispatch(Lifecycle.Event.ON_START);    }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);            }        }    }}

在Activity中调用的injectIfNeededIn方法里,ReportFragment检查了这个Activity有没有已经持有了ReportFragment ,如果没有就新增一个,这样ReportFragment就共享了该Activity的生命状态。然后在生命周期方法onXX方法中发送事件,发送的方式在dispatch方法里。也就是根据Activity的不同(实际上在我的这版代码里,LifecycleRegistryOwner已经被废弃了,因此实际上只会走activity instanceof LifecycleOwner这条线),调用getLifecycle获取Activity的Lifecycle(也就是LifecycleRegistry),然后调用它的handleLifecycleEvent方法,将事件发送出去。

Fragment 实现 LifecycleOwner

接下来看Fragment(androidx.fragment.app.Fragment)的实现了。其实Fragment的实现更简单,它直接实现了LifecycleOwner接口:

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

Fragment同样是通过LifecycleRegistry来发送生命周期事件和管理订阅者的。

小结

通过上面的介绍,LIfecycles体系的大体样子已经描述出来了,Activity 和 Fragment 通过继承LifecycleOwner 来提供getLifecycle接口,但实际上Lifecycle的功能实现是由LifecycleRegistry来完成的;如果我们要监听组件的生命周期,则需要继承LifecycleObserver或它的子类,通过相应注解或者override方法来在生命周期变化时获取对应生命周期改变事件的回调。然后通过该组件的getLifecycle方法获取到它的Lifecycle,再调用Lifecycle的addObserver方法完成订阅者的注册,还要在合适的时机调用removeObserver完成反注册。同时要注意的是,LIfecycles的大部分接口都规定了在主线程调用,因此,这个框架并不是线程安全的。
可以看出LifecycleRegistry是LIfecycles框架最重要的一个类,因此,我会在下一节里用一整节的篇幅详细分析它的实现。

更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. Python list sort方法的具体使用
  3. python list.sort()根据多个关键字排序的方法实现
  4. Android上实现zlib解压缩的方法 Inflater用法
  5. 如何去掉Android(安卓)kitkat中的红框
  6. Android(安卓)SDK下载和更新失败的解决方法!!!
  7. android RadioButton文字居中的方法
  8. 编译NotificationManagerService.java文件的方法
  9. Android(安卓)建造者(Builder)模式

随机推荐

  1. 关于 android.support.v7.widget.ListPop
  2. E/JavaBinder:FAILED BINDER TRANSACTION
  3. Android:无法在同一部手机上执行通过Linu
  4. [android基础]《疯狂android讲义》重点整
  5. 为什么使用KML数据检索Android版Google方
  6. Android开机启动过程分析
  7. 为什么Android API中有这么多花车?
  8. Android中Broadcast Receiver的两种注册
  9. android ontouch和onclick冲突处理
  10. android:使用网络通信技术从客户端直接获