Jetpack — AAC架构组件之Lifecycle

Posted Chin_style

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Jetpack — AAC架构组件之Lifecycle相关的知识,希望对你有一定的参考价值。

一,前期基础知识储备

查看源图像

1)AAC架构

android Architecture Components,简称 AAC,一个处理UI的生命周期与数据的持久化的架构。

核心组件:Lifecycle, LiveData, ViewModel 以及 Room。

主要作用:

  • 通过它可以非常优雅的让数据与界面交互
  • 并做一些持久化的东西
  • 高度解耦
  • 自动管理生命周期
  • 而且不用担心内存泄漏的问题

2)不使用Lifecycle时的常规操作

解耦是软件开发中永远追求的,在Android开发中,解藕很大程度上表现为系统组件的生命周期与普通组件之间的解藕,因为普通组件在使用过程中需要依赖系统组件的的生命周期。

举个例子,我们经常需要在页面的onCreate()方法中对组件进行初始化,然后在onStop()中停止组件,或者在onDestory()方法中对进行进行销毁。事实上,这样的工作非常繁琐,会让页面和页面耦合度变高,但又不得不做,因为如果不即时的释放资源,有可能会导致内存泄露。例如,下面是一个在Activity的不同生命周期方法中监听调用的例子,代码如下:

public class MainActivity extends AppCompatActivity {
    private MyListener myListener;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        myListener = new MyListener(MainActivity.this);
    }
    @Override
    protected void onStart() {
        super.onStart();
        myListener.start();
    }
    @Override
    protected void onStop() {
        super.onStop();
        myListener.stop();
    }
}

public class MyListener {
    public MyListener(Context context) {...}
    void start() {...}
    void stop() {...}
}

虽然,代码执行起来并没有什么问题,但在实际开发中可能会有多个组件在Activity的生命周期方法中回调,这样Activity的生命周期的方法中可能就需要编写大量的代码,这就使得它们难以维护。同时MyListener的构造方法中会传入上下文对象,这就使得其持有了Activity的实例对象,在某些情况,这会引起内存泄漏。

我们希望在对组件进行管理时,不依赖页面的生命周期的回调方法,同时当页面生命周期发生改变时,也能够即时的收到通知

3)使用Lifecycle

Lifecycle 就是具有生命周期感知能力的组件。简单的理解就是,当Activity/Fragment的生命周期产生变化时,Lifecycle组件会感应相应的生命周期变化。所以只要对其进行监听,就可以实现不依赖页面而能及时收到通知。

监听Activity,Fragment的生命周期,其使用步骤非常简单:

  • 实现生命周期观察者接口 — 观察者实现LifecycleObserver,方法上使用OnLifecycleEvent注解关注对应生命周期,生命周期触发时就会执行对应方法。
  • 注册生命周期观察者 — 生命周期拥有者 使用getLifecycle()获取Lifecycle实例,然后代用addObserver()添加观察者。

 

二,上代码,具体实现

查看源图像

1)引入依赖,Androidx 项目创建时会自动添加依赖:

implementation 'androidx.appcompat:appcompat:1.1.0'

因为appcompat依赖了androidx.fragment,而androidx.fragment下依赖了ViewModel和 LiveData,LiveData内部又依赖了Lifecycle。

非Androidx 项目手动添加依赖:

implementation "android.arch.lifecycle:extensions:1.1.1"

2)注册生命周期观察者

public class MainActivity extends AppCompatActivity implements IView {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ① // 普通实现
          getLifecycle().addObserver(new CustomObserver());
          getLifecycle().addObserver(new LifecycleObserverClass());
        ③ // MVP实现
          homePresenter = new HomePresenter(this);
          getLifecycle().addObserver(homePresenter);
    }
}

Activity(或Fragment)是生命周期的拥有者,通过getLifecycle方法获取到生命周期Lifecycle对象,Lifecycle对象使用addObserver方法给自己添加观察者,即new出Observer对象。当Lifecycle的生命周期发生变化时,Observer就可以感知到。如果使用了MVP的方式实现,则这里的P层化身为观察者。

3) 实现生命周期观察者接口

常见的一共有三种实现方式,开发者可以根据自己的需求选择适合自己的实现方式:

自定义类,直接实现LifecycleObserver接口,同时自定义方法,为方法打上注解,等到对应生命周期方法执行的时候,就可以调用定义好的方法了;

public class CustomObserver implements LifecycleObserver {
    @OnLifecycleEvent(value = Lifecycle.Event.ON_CREATE)
    public void connect_create() { }

    @OnLifecycleEvent(value = Lifecycle.Event.ON_START)
    public void connect_start() { }

    @OnLifecycleEvent(value = Lifecycle.Event.ON_RESUME)
    public void connect_resume() { }

    @OnLifecycleEvent(value = Lifecycle.Event.ON_PAUSE)
    public void connect_pause() { }

    @OnLifecycleEvent(value = Lifecycle.Event.ON_STOP)
    public void connect_stop() { }

    @OnLifecycleEvent(value = Lifecycle.Event.ON_DESTROY)
    public void connect_destroy() { }
}

首先CustomObserver实现了接口LifecycleObserver,LifecycleObserver用于标记一个类是生命周期观察者。然后在connect_resume()、connect_pause()上分别都加了@OnLifecycleEvent注解,且value分别是Lifecycle.Event.ON_RESUME、Lifecycle.Event.ON_PAUSE,这个效果就是:connect_resume()会在ON_RESUME时执行,connect_pause()会在ON_PAUSE时执行。

自定义接口,继承自LifecycleObserver接口,内部自定义方法,并且打上注解;而后自定义一个类进行实现:

interface ILifecycleObserver extends LifecycleObserver {

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

    ... ...

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

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

public class LifecycleObserverClass implements ILifecycleObserver {

    @Override
    public void onCreate(LifecycleOwner owner) { }
    
    ... ...

    @Override
    public void onDestroy(LifecycleOwner owner) { }

    @Override
    public void onLifecycleChanged(LifecycleOwner owner, Lifecycle.Event event) {
        Log.d(TAG, "onLifecycleChanged: " + owner + ",,,," + event);
    }
}

自定义接口,继承自LifecycleObserver接口,内部自定义方法,此时不打上注解;而后自定义一个类进行实现,类里面实现接口方法后,打上注解:

interface FullLifecycle extends LifecycleObserver {
    void onCreate(LifecycleOwner owner);

    ... ...

    void onDestroy(LifecycleOwner owner);
}

public abstract class BasePresenter implements FullLifecycle {

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    @Override
    public void onCreate(LifecycleOwner owner) { }
    
    ... ...

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    @Override
    public void onDestroy(LifecycleOwner owner) { }
}

注意:② ③中的自定义的构造方法中都传入了一个LifecycleOwner的参数,这个参数可以在结合LiveData一起时使用。

4)联合MVP进行实现

新建一个View接口对象,执行UI逻辑;

interface IView {
    void showView();

    void hideView();
}

新建一个HomePresenter,继承自上面的BasePresenter,作为P层接口;

public class HomePresenter extends BasePresenter {
    private IView iView;
    public HomePresenter(IView view) {
        iView = view;
    }

    @Override
    public void onCreate(LifecycleOwner owner) {
        super.onCreate(owner);
        if (owner.getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.CREATED)) {
            iView.showView();
        }
    }

    @Override
    public void onPause(LifecycleOwner owner) {
        super.onPause(owner);
        iView.hideView();
    }

    @Override
    public void onDestroy(LifecycleOwner owner) {
        super.onDestroy(owner);
        iView.hideView();
    }
}

Activity的代码如下:

public class MainActivity extends AppCompatActivity implements IView {
    private HomePresenter homePresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        homePresenter = new HomePresenter(this);
        getLifecycle().addObserver(homePresenter);
    }

    @Override
    public void showView() { }

    @Override
    public void hideView() { }
}

这里是让Presenter实现LifecycleObserver接口,同样在方法上注解要触发的生命周期,最后在Activity中作为观察者添加到Lifecycle中。

这样做好处是啥呢?当Activity生命周期发生变化时,HomePresenter就可以感知并执行方法,不需要在MainActivity的多个生命周期方法中调用HomePresenter的方法了

所有方法调用操作都由组件本身管理:Presenter类自动感知生命周期,如果需要在其他的Activity/Fragment也使用这个Presenter,只需添加其为观察者即可。

让各个组件存储自己的逻辑,减轻Activity/Fragment中代码,更易于管理;

    @Override
    public void onCreate(LifecycleOwner owner) {
        super.onCreate(owner);
        if (owner.getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.CREATED)) {
            iView.showView();
        }
    }

另外,注意到 onCreate()中的回调,对当前生命周期状态进行了检查:至少处于CREATED状态才会继续执行showView()方法,也就是保证了Activity停止后不会调用方法,减少了内存泄漏的可能;

 

三,期间几个重要的对象

  • LifecycleOwner:生命周期的事件分发者,该接口的实现类表示能够为外部提供Lifecycle实例。系统框架中,接口的实现类为ComponentActivity和Fragment,两者提供的Lifecycle对象,是系统框架实现中Lifecycle的唯一子类LifecycleRegistry。可以在 Activity、Fragment生命周期改变时,通过LifecycleRegistry类处理对应的生命周期事件,并通知 LifecycleObserver这个观察者;
  • Lifecycle:是被观察者,用于存储有关组件(如 Activity 或 Fragment)的生命周期状态的信息,并允许其他对象观察此状态;
  • LifecycleObserver:生命周期的观察者,该接口的实现类表示为关注生命周期的观察者,可以通过被LifecycleRegistry类通过 addObserver(LifecycleObserver o)方法注册,被注册后,LifecycleObserver便可以观察到LifecycleOwner对应的生命周期事件;
  • LifecycleRegistry:Lifecycle的实现类。控制中心。它负责控制state的转换、接受分发event事件。
  • Lifecycle.Event:分派的生命周期事件。这些事件映射到 Activity 和 Fragment 中的回调事件。
  • Lifecycle.State:生命周期当前的状态。Lifecycle组件的当前状态。

Event枚举:注意没有onRestart对应的状态;定一系列枚举常量,和 Activity、Fragment 的生命周期是一一对应的,可以响应其生命周期,其中多了一个ON_ANY,它是可以匹配任何事件的,Event 的使用是和 LifecycleObserver 配合使用的。

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

State枚举:当前Lifecycle的自己的目前的状态,它是和Event配合使用的。

public enum State {
        DESTROYED,
        INITIALIZED,
        CREATED,
        STARTED,
        RESUMED;
        public boolean isAtLeast(@NonNull State state) {
            return compareTo(state) >= 0;
        }
    }

Event和State之间的关系:

Lifecycle的常见的使用场景:

  • Lifecycle 的应用场景非常广泛,我们可以利用 Lifecycle 的机制来帮助我们将一切跟生命周期有关的业务逻辑全都剥离出去,进行完全解耦。
    • 比如视频的暂停与播放,
    • Handler 的消息移除,
    • 网络请求的取消操作,
    • Presenter 的 attach&detach View
    • 暂停和恢复动画绘制
    • 并且可以以一个更加优雅的方式实现,还我们一个更加干净可读的 Activity & Fragment。
  • 关于网络请求的取消操作
  • 停止和开启视频缓冲
    • 使用支持生命周期的组件尽快开始视频缓冲,但是将播放推迟到应用程序完全启动。 还可以使用可识别生命周期的组件在应用程序销毁时终止缓冲。
  • 启动和停止网络连接
    • 使用可感知生命周期的组件可以在应用程序处于前台状态时实时更新(流式传输)网络数据,并在应用程序进入后台时自动暂停。
  • 暂停和恢复动画绘制
    • 当应用程序在后台运行时,使用生命周期感知组件处理暂停动画绘制,并在应用程序在前台运行后恢复绘制。

 

最后总结:

  1. 先声明了一个观察者,用来监听被观察者(Activity/Fragment);
  2. 观察者通过实现LifecycleObserver接口,使用注解来监听被观察者发生的变化;
  3. 那么是如何监听的,这次就使用到了lifecycle。lifecycle相当于一个桥梁,把两者关联在一起;
  4. 被观察者通过实现LifecycleOwner接口先连接了桥梁;
  5. 观察者则通过getLifecycle().addObserver()方法也建立起连接。

 

参考文章《Android Jetpack架构组件 — Lifecycle入坑指南》《Lifecycle详细分析》《Jetpack AAC完整解析,Lifecycle 完全掌握

 

以上是关于Jetpack — AAC架构组件之Lifecycle的主要内容,如果未能解决你的问题,请参考以下文章

Android安卓进阶技巧之Kotlin结合Jetpack构建MVVM

2022年Android面试之Jetpack(AAC框架)篇

JetPack 使用推荐

JetPack 使用推荐

Android Jetpack架构组件之WorkManager

JetPack架构---Lifecycle生命周期相关与原理