Android官方架构组件:Lifecycle详解&原理分析

简介: 应该是 Android Jetpack 讲解的最好的博客系列: Android官方架构组件Paging:分页库的设计美学 Android官方架构组件Navigation:大巧不工的Fragment管理框架 Android官方架构组件Lifecycle:生命周期组件详解&原理分析 概述 在过去的谷歌IO大会上,Google官方向我们推出了 Android Architecture Components,其中谈到Android组件处理生命周期的问题,向我们介绍了 Handling Lifecycles。

应该是 Android Jetpack 讲解的最好的博客系列:

 ● Android官方架构组件Paging:分页库的设计美学
 ● Android官方架构组件Navigation:大巧不工的Fragment管理框架
 ● Android官方架构组件Lifecycle:生命周期组件详解&原理分析
概述

在过去的谷歌IO大会上,Google官方向我们推出了 Android Architecture Components,其中谈到Android组件处理生命周期的问题,向我们介绍了 Handling Lifecycles。

同时,如何利用 android.arch.lifecycle 包提供的类来控制数据、监听器等的 lifecycle。同时,LiveData 与 ViewModel 的 lifecycle 也依赖于 Lifecycle 框架。

经过公司内部的技术交流小组的探讨后,不少小伙伴觉得这个框架本身尚未成熟(当时的 Android Architecture Components组件还处于Alpha版本),再加上本身并没有足够的说服力让我们抛弃RxJava+RxAndroid全家桶转身投奔LiveData ,而Room 这个数据库框架本身也有很多同样优秀的三方库可以替代,因此我渐渐把这个框架的学习计划搁置了。

不久前, Android Architecture Components 正式Release, Lifecycle也正式植入进了SupportActivity(AppCompatActivity的基类)和Fragment中,我觉得还是有必要去尝试学习google的这个框架,不管有没有用到,我相信其本身的设计思想也会对我有很大的帮助。

一、Lifecycle简介&基础使用
为什么要引进Lifecycle?

我们在处理Activity或者Fragment组件的生命周期相关时,不可避免会遇到这样的问题:

我们在Activity的onCreate()中初始化某些成员(比如MVP架构中的Presenter,或者AudioManager、MediaPlayer等),然后在onStop中对这些成员进行对应处理,在onDestroy中释放这些资源,这样导致我们的代码也许会像这样:

 

class MyPresenter{
    public MyPresenter() {
    }

    void create() {
        //do something
    }

    void destroy() {
        //do something
    }
}

class MyActivity extends AppCompatActivity {
    private MyPresenter presenter;

    public void onCreate(...) {
        presenter= new MyPresenter ();
        presenter.create();
    }

    public void onDestroy() {
        super.onDestroy();
        presenter.destory();
    }
}

代码没有问题,关键问题是,实际生产环境中 ,这样的代码会非常复杂,你最终会有太多的类似调用并且会导致 onCreate() 和 onDestroy() 方法变的非常臃肿。

解决方案

Lifecycle 是一个类,它持有关于组件(如 Activity 或 Fragment)生命周期状态的信息,并且允许其他对象观察此状态。

我们只需要2步:

1、Prestener继承LifecycleObserver接口

 

public interface IPresenter extends LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    void onCreate(@NotNull LifecycleOwner owner);

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    void onDestroy(@NotNull LifecycleOwner owner);

    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    void onLifecycleChanged(@NotNull LifecycleOwner owner,
                            @NotNull Lifecycle.Event event)
;
}

public class BasePresenter implements IPresenter {

    private static final String TAG = "com.qingmei2.module.base.BasePresenter";    

    @Override
    public void onLifecycleChanged(@NotNull LifecycleOwner owner, @NotNull Lifecycle.Event event) {

    }

    @Override
    public void onCreate(@NotNull LifecycleOwner owner) {
        Log.d("tag""BasePresenter.onCreate" + this.getClass().toString());
    }

    @Override
    public void onDestroy(@NotNull LifecycleOwner owner) {
        Log.d("tag""BasePresenter.onDestroy" + this.getClass().toString());
    }
}

这里我直接将我想要观察到Presenter的生命周期事件都列了出来,然后封装到BasePresenter 中,这样每一个BasePresenter 的子类都能感知到Activity容器对应的生命周期事件,并在子类重写的方法中,对应相应行为。

2、在Activity/Fragment容器中添加Observer:

 

public class MainActivity extends AppCompatActivity {
    private IPresenter mPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("tag""onCreate" + this.getClass().toString());
        setContentView(R.layout.activity_main);
        mPresenter = new MainPresenter(this);
        getLifecycle().addObserver(mPresenter);//添加LifecycleObserver
    }

    @Override
    protected void onDestroy() {
        Log.d("tag""onDestroy" + this.getClass().toString());
        super.onDestroy();
    }
}

如此,每当Activity发生了对应的生命周期改变,Presenter就会执行对应事件注解的方法:

除onCreate和onDestroy事件之外,Lifecycle一共提供了所有的生命周期事件,只要 
通过注解进行声明,就能够使LifecycleObserver观察到对应的生命周期事件:

 

//以下为logcat日志
01-08 23:21:01.702  D/tag: onCreate  class com.qingmei2.mvparchitecture.mvp.ui.MainActivity
01-08 23:21:01.778  D/tag: onCreate  class com.qingmei2.mvparchitecture.mvp.presenter.MainPresenter

01-08 23:21:21.074  D/tag: onDestroy  class com.qingmei2.mvparchitecture.mvp.presenter.MainPresenter
01-08 23:21:21.074  D/tag: onDestroy  class com.qingmei2.mvparchitecture.mvp.ui.MainActivity

~

 

 public enum Event {
        /**
         * Constant for onCreate event of the {@link LifecycleOwner}.
         */

        ON_CREATE,
        /**
         * Constant for onStart event of the {@link LifecycleOwner}.
         */

        ON_START,
        /**
         * Constant for onResume event of the {@link LifecycleOwner}.
         */

        ON_RESUME,
        /**
         * Constant for onPause event of the {@link LifecycleOwner}.
         */

        ON_PAUSE,
        /**
         * Constant for onStop event of the {@link LifecycleOwner}.
         */

        ON_STOP,
        /**
         * Constant for onDestroy event of the {@link LifecycleOwner}.
         */

        ON_DESTROY,
        /**
         * An {@link Event Event} constant that can be used to match all events.
         */

        ON_ANY
    }

二、原理分析
先说结论:

借鉴Android 架构组件(一)——Lifecycle, @ShymanZhu的一张图进行简单的概括:

2995b3c83c6d6716bf4714122a4b2460fa3d1dd8

Lifecycle组件原理

我们先将重要的这些类挑选出来:

LifecycleObserver接口( Lifecycle观察者):实现该接口的类,通过注解的方式,可以通过被LifecycleOwner类的addObserver(LifecycleObserver o)方法注册,被注册后,LifecycleObserver便可以观察到LifecycleOwner的生命周期事件。

LifecycleOwner接口(Lifecycle持有者):实现该接口的类持有生命周期(Lifecycle对象),该接口的生命周期(Lifecycle对象)的改变会被其注册的观察者LifecycleObserver观察到并触发其对应的事件。

Lifecycle(生命周期):和LifecycleOwner不同的是,LifecycleOwner本身持有Lifecycle对象,LifecycleOwner通过其Lifecycle getLifecycle()的接口获取内部Lifecycle对象。

State(当前生命周期所处状态):如图所示。

Event(当前生命周期改变对应的事件):如图所示,当Lifecycle发生改变,如进入onCreate,会自动发出ON_CREATE事件。

了解了这些类和接口的职责,接下来原理分析就简单很多了,我们以Fragment为例,来看下实际Fragment等类和上述类或接口的联系:

1、Fragment:LifecycleOwner

Fragment(Activity同理,我们 本文以Fragment为例,下同):实现了LifecycleOwner接口,这意味着Fragment对象持有生命周期对象(Lifecycle),并可以通过Lifecycle getLifecycle()方法获取内部的Lifecycle对象:

 

public class Fragment implements xxxLifecycleOwner {

    //...省略其他

   LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
}

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

可以看到,实现的getLifecycle()方法,实际上返回的是 LifecycleRegistry 对象,LifecycleRegistry对象实际上继承了 Lifecycle,这个下文再讲。

持有Lifecycle有什么作用呢?实际上在Fragment对应的生命周期内,都会发送对应的生命周期事件给内部的 LifecycleRegistry对象处理:

 

public class Fragment implements xxxLifecycleOwner {
    //...
    void performCreate(Bundle savedInstanceState) {
        onCreate(savedInstanceState);  //1.先执行生命周期方法
        //...省略代码
        //2.生命周期事件分发
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
    }

    void performStart() {
        onStart();
        //...
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    }

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

    void performPause() {
        //3.注意,调用顺序变了
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
        //...
        onPause();
    }

    void performStop() {
       mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
        //...
        onStop();
    }

    void performDestroy() {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
        //...
        onDestroy();
    }
}

随着Fragment不同走到不同的生命周期,除了暴露给我们的生命周期方法onCreate/onStart/…./onDestroy等,同时,Fragment内部的Lifecycle对象(就是mLifecycleRegistry)还将生命周期对应的事件作为参数传给了 handleLifecycleEvent() 方法。

同时,你会发现Fragment中performCreate()、performStart()、performResume()会先调用自身的onXXX()方法,然后再调用LifecycleRegistry的handleLifecycleEvent()方法;而在performPause()、performStop()、performDestroy()中会先LifecycleRegistry的handleLifecycleEvent()方法 ,然后调用自身的onXXX()方法。

参照Android 架构组件(一)——Lifecycle, @ShymanZhu文中的时序图:

3a193bc2bebd0cd9b23db69f63519b9c15ed0bb5

我们从图中可以看到,当Fragment将生命周期对应的事件交给其内部的Lifecycle处理后, LifecycleObserver (就是我们上文自定义的Presenter),就能够接收到对应的生命周期事件,这是如何实现的呢?

2、LifecycleRegistry:Lifecycle
首先确认一点,LifecycleRegistry 就是 Lifecycle 的子类:

 

public class LifecycleRegistry extends Lifecycle {
}

我们看一下 Lifecycle 类

 

public abstract class Lifecycle {

        //注册LifecycleObserver (比如Presenter)
        public abstract void addObserver(@NonNull LifecycleObserver observer);
        //移除LifecycleObserver 
        public abstract void removeObserver(@NonNull LifecycleObserver observer);
        //获取当前状态
        public abstract State getCurrentState();

        public enum Event {
            ON_CREATE,
            ON_START,
            ON_RESUME,
            ON_PAUSE,
            ON_STOP,
            ON_DESTROY,
            ON_ANY
        }

       public enum State {
            DESTROYED,
            INITIALIZED,
            CREATED,
            STARTED,
            RESUMED;

            public boolean isAtLeast(@NonNull State state) {
                return compareTo(state) >= 0;
            }
       }
}

Lifecycle没什么要讲的,几个抽象方法也能看懂,作为Lifecycle的子类,LifecycleRegistry 同样也能通过addObserver方法注册LifecycleObserver (就是Presenter),当LifecycleRegistry 本身的生命周期改变后(可以想象,内部一定有一个成员变量State记录当前的生命周期),LifecycleRegistry 就会逐个通知每一个注册的LifecycleObserver ,并执行对应生命周期的方法。

我们看一下LifecycleRegistry 的handleLifecycleEvent()方法:

 

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

看方法的名字我们就可以知道,handleLifecycleEvent方法会通过 getStateAfter 获取当前应处的状态并修改 Lifecycle本身的State 值,紧接着遍历所 LifecycleObserver 并同步且通知其状态发生变化,因此就能触发LifecycleObserver 对应的生命周期事件。

实际上LifecycleRegistry 本身还是有很多值得一提之处,本文只阐述清楚原理,暂不涉及源码详解。

一些小Tips
1、尝试复用LifecycleRegistry

首先,LifecycleRegistry 本身就是一个成熟的 Lifecycle 实现类,它被实例化在Activity和Fragment中使用,如果我们需要自定义LifecycleOwner 并实现接口需要返回一个Lifecycle实例,完全可以直接在自定义LifecycleOwner中new一个LifecycleRegistry成员并返回它(简而言之就是:直接拿来用即可)。

以下是Google官方文档:

 

LifecycleRegistry: 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.

2、注解和DefaultLifecycleObserver的取舍

其次,Google的Lifecycle库中提供了一个 DefaultLifecycleObserver 类,方便我们直接实现LifecycleObserver接口,相比较于文中demo所使用的注解方式,Google官方更推荐我们使用 DefaultLifecycleObserver 类,并声明

一旦Java 8成为Android的主流,注释将被弃用,所以介于DefaultLifecycleObserver和注解两者之间,更推荐使用 DefaultLifecycleObserver 。

官方原文:

 

/*
 * If you use <b>Java 8 Language</b>, then observe events with {@link DefaultLifecycleObserver}.
 * To include it you should add {@code "android.arch.lifecycle:common-java8:<version>"} to your
 * build.gradle file.
 * <pre>
 * class TestObserver implements DefaultLifecycleObserver {
 *     {@literal @}Override
 *     public void onCreate(LifecycleOwner owner) {
 *         // your code
 *     }
 * }
 * </pre>
 * If you use <b>Java 7 Language</b>, Lifecycle events are observed using annotations.
 * Once Java 8 Language becomes mainstream on Android, annotations will be deprecated, so between
 * {@link DefaultLifecycleObserver} and annotations,
 * you must always prefer {@code DefaultLifecycleObserver}.
 */

* 3、Lifecycles 的最佳实践

本小节内容节选自《[译] Architecture Components 之 Handling Lifecycles》 
作者:zly394 
链接:https://juejin.im/post/5937e1c8570c35005b7b262a

保持 UI 控制器(Activity 和 Fragment)尽可能的精简。它们不应该试图去获取它们所需的数据;相反,要用 ViewModel来获取,并且观察 LiveData将数据变化反映到视图中。

尝试编写数据驱动(data-driven)的 UI,即 UI 控制器的责任是在数据改变时更新视图或者将用户的操作通知给 ViewModel。

将数据逻辑放到 ViewModel 类中。ViewModel 应该作为 UI 控制器和应用程序其它部分的连接服务。注意:不是由 ViewModel 负责获取数据(例如:从网络获取)。相反,ViewModel 调用相应的组件获取数据,然后将数据获取结果提供给 UI 控制器。

使用Data Binding来保持视图和 UI 控制器之间的接口干净。这样可以让视图更具声明性,并且尽可能减少在 Activity 和 Fragment 中编写更新代码。如果你喜欢在 Java 中执行该操作,请使用像Butter Knife 这样的库来避免使用样板代码并进行更好的抽象化。

如果 UI 很复杂,可以考虑创建一个 Presenter 类来处理 UI 的修改。虽然通常这样做不是必要的,但可能会让 UI 更容易测试。

不要在 ViewModel 中引用View或者 Activity的 context。因为如果ViewModel存活的比 Activity 时间长(在配置更改的情况下),Activity 将会被泄漏并且无法被正确的回收。

总结

总而言之,Lifecycle还是有可取之处的,相对于其它架构组件之间的配合,Lifecycle更简单且独立(实际上配合其他组件味道更佳)。

本文旨在分析Lifecycle框架相关类的原理,将不会对Lifecycle每一行的源码进行深入地探究,如果有机会,笔者将尝试写一篇源码详细解析。

参考&感谢
 ● Lifecycle-aware Components 源码分析 @chaosleong
 ● Android 架构组件(一)——Lifecycle @ShymanZhu

原文发布时间为:2018-09-17
本文来自云栖社区合作伙伴“ Android开发中文站”,了解相关信息可以关注“ Android开发中文站”。
相关文章
|
1月前
|
存储 Kubernetes 负载均衡
Kubernetes的“厨房”:架构是菜谱,组件是厨具,资源对象是食材(下)
本文深入探讨了Kubernetes(K8s)的架构、核心组件以及资源对象。Kubernetes作为一个开源的容器编排系统,通过其独特的架构设计和丰富的组件,实现了对容器化应用程序的高效管理和扩展。通过本文的介绍,读者可以深入了解Kubernetes的架构、核心组件以及资源对象,从而更好地应用和管理容器化应用程序。Kubernetes的灵活性和可扩展性使得它成为容器编排领域的领先者,为企业提供了强大的容器运行环境。
|
26天前
|
设计模式 安全 Java
【分布式技术专题】「Tomcat技术专题」 探索Tomcat技术架构设计模式的奥秘(Server和Service组件原理分析)
【分布式技术专题】「Tomcat技术专题」 探索Tomcat技术架构设计模式的奥秘(Server和Service组件原理分析)
31 0
|
26天前
|
NoSQL Java Redis
【分布式技术专题】「分布式技术架构」手把手教你如何开发一个属于自己的分布式锁的功能组件(二)
【分布式技术专题】「分布式技术架构」手把手教你如何开发一个属于自己的分布式锁的功能组件
15 0
|
2天前
|
传感器 Java Android开发
Android HAL深入探索(1): 架构概述
Android HAL深入探索(1): 架构概述
18 1
|
13天前
|
存储 数据库 Android开发
构建高效安卓应用:采用Jetpack架构组件优化用户体验
【4月更文挑战第12天】 在当今快速发展的数字时代,Android 应用程序的流畅性与响应速度对用户满意度至关重要。为提高应用性能并降低维护成本,开发者需寻求先进的技术解决方案。本文将探讨如何利用 Android Jetpack 中的架构组件 — 如 LiveData、ViewModel 和 Room — 来构建高质量的安卓应用。通过具体实施案例分析,我们将展示这些组件如何协同工作以实现数据持久化、界面与逻辑分离,以及确保数据的即时更新,从而优化用户体验并提升应用的可维护性和可测试性。
|
24天前
|
移动开发 前端开发 数据管理
构建高效Android应用:采用MVVM架构与LiveData的全面指南
在移动开发领域,构建一个既快速又可靠的应用对于开发者来说至关重要。随着Android Jetpack组件的推出,MVVM(Model-View-ViewModel)架构和LiveData已成为实现响应式、可测试且易于维护应用的首选解决方案。本文将深入探讨如何在Android应用中实施MVVM模式,以及如何利用LiveData来优化UI组件的数据更新流程,确保用户界面与业务逻辑之间的高度解耦和流畅交互。
18 4
|
26天前
|
存储 Java 应用服务中间件
【分布式技术专题】「架构实践于案例分析」盘点互联网应用服务中常用分布式事务(刚性事务和柔性事务)的原理和方案
【分布式技术专题】「架构实践于案例分析」盘点互联网应用服务中常用分布式事务(刚性事务和柔性事务)的原理和方案
48 0
|
1月前
|
SpringCloudAlibaba Java 持续交付
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(一)基础知识+各个组件介绍+聚合父工程创建
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(一)基础知识+各个组件介绍+聚合父工程创建
86 1
|
1月前
|
Kubernetes API 调度
Kubernetes的“厨房”:架构是菜谱,组件是厨具,资源对象是食材(上)
本文深入探讨了Kubernetes(K8s)的架构、核心组件以及资源对象。Kubernetes作为一个开源的容器编排系统,通过其独特的架构设计和丰富的组件,实现了对容器化应用程序的高效管理和扩展。通过本文的介绍,读者可以深入了解Kubernetes的架构、核心组件以及资源对象,从而更好地应用和管理容器化应用程序。Kubernetes的灵活性和可扩展性使得它成为容器编排领域的领先者,为企业提供了强大的容器运行环境。
|
1月前
|
监控 JavaScript 安全
监控内网电脑软件设计与实现:基于Node.js的服务器端架构分析
在当今信息技术高度发达的时代,监控内网电脑的需求日益增长。企业需要确保网络安全,个人用户也需要监控家庭网络以保护隐私和安全。本文将介绍一种基于Node.js的服务器端架构,用于设计和实现监控内网电脑软件。
100 0