“终于懂了“系列:Jetpack AAC完整解析(一)Lifecycle 完全掌握

本文详细介绍了Android Jetpack中的Lifecycle组件,旨在帮助开发者更好地管理Activity和Fragment的生命周期。内容涵盖Lifecycle的背景、使用方法、源码分析及自定义LifecycleOwner。通过源码解析,展示了Lifecycle如何在不同生命周期状态下触发观察者方法,以及如何解决生命周期管理中的常见问题。了解和掌握Lifecycle是Android架构组件AAC中的重要一环,对于实现MVVM架构至关重要。
摘要由CSDN通过智能技术生成

Jetpack AAC 系列文章:

“终于懂了“系列:Jetpack AAC完整解析(一)Lifecycle 完全掌握!

“终于懂了“系列:Jetpack AAC完整解析(二)LiveData 完全掌握!

“终于懂了“系列:Jetpack AAC完整解析(三)ViewModel 完全掌握!

“终于懂了“系列:Jetpack AAC完整解析(四)MVVM - Android架构探索!

“终于懂了“系列:Jetpack AAC完整解析(五)DataBinding 重新认知!

欢迎关注我的 公 众 号,微信搜索 胡飞洋 ,文章更新可第一时间收到。

一、Android Jetpack 介绍

1.1 Jetpack是啥

官方定义如下:

Jetpack 是一个由多个库组成的套件,可帮助开发者遵循最佳做法,减少样板代码并编写可在各种 Android 版本和设备中一致运行的代码,让开发者精力集中编写重要的代码。

JetPack更多是一种概念和态度,它是谷歌开发的非Android Framework SDK自带、但同时是Android开发必备的/推荐的SDK/开发规范合集。相当于Google把自己的Android生态重新整理了一番,确立了Android未来的开发大方向。

使用Jetpack有如下好处:

  • 遵循最佳做法,Android Jetpack 组件采用最新的设计方法构建,具有向后兼容性,可以减少崩溃和内存泄露。
  • 消除样板代码,Android Jetpack 可以管理各种繁琐的 Activity(如后台任务、导航和生命周期管理),以便您可以专注于打造出色的应用。
  • 减少不一致,这些库可在各种 Android 版本和设备中以一致的方式运作,助您降低复杂性。

Jetpack

Jetpack原意为 喷气背包,Android背上Jetpack后就直冲云霄,这很形象了~

也就是,Jetpack是帮助开发者高效开发应用的工具集。那么这一工具包含了哪些内容呢?

1.2 Jetpack分类

分类如下图(现在官网已经找不到这个图了):

Android Jetpack 组件覆盖以下 4 个方面:架构(Architecture)、基础(Foundation)、行为(Behavior) 、界面(UI)。

真正的精华主要是Architecture,全称是Android Architecture Component(AAC), 即Android架构组件

其包括比较成功的Lifecycle、LiveData、ViewModel,同时也是我们使用MVVM模式的最好框架工具,可以组合使用,也可以单独使用。

以上基本都是官网的介绍,我们主要目标就是掌握AAC的组件,深入理解进而运用到MVVM架构中。

如题,我们学习Jetpack的重点就是AAC,这篇就从基础的Lifecycle讲起。

二、Lifecycle

Lifecycle,顾名思义,是用于帮助开发者管理Activity和Fragment 的生命周期,它是LiveData和ViewModel的基础。下面就先介绍为何及如何使用Lifecycle。

2.1 Lifecycle之前

官方文档有个例子 来说明使用Lifecycle之前是如何生命周期管理的:

假设我们有一个在屏幕上显示设备位置的 Activity。常见的实现可能如下所示:

    class MyLocationListener {
   
        public MyLocationListener(Context context, Callback callback) {
   
            // ...
        }

        void start() {
   
            // 连接系统定位服务
        }

        void stop() {
   
            // 断开系统定位服务
        }
    }

    class MyActivity extends AppCompatActivity {
   
        private MyLocationListener myLocationListener;

        @Override
        public void onCreate(...) {
   
            myLocationListener = new MyLocationListener(this, (location) -> {
   
                // 更新 UI
            });
        }

        @Override
        public void onStart() {
   
            super.onStart();
            myLocationListener.start();
            // 管理其他需要响应activity生命周期的组件
        }

        @Override
        public void onStop() {
   
            super.onStop();
            myLocationListener.stop();
            // 管理其他需要响应activity生命周期的组件
        }
    }
    

虽然此示例看起来没问题,但在真实的应用中,最终会有太多管理界面和其他组件的调用,以响应生命周期的当前状态。管理多个组件会在生命周期方法(如 onStart() 和 onStop())中放置大量的代码,这使得它们难以维护。

此外,无法保证组件会在 Activity 或 Fragment 停止之前启动myLocationListener。在我们需要执行长时间运行的操作(如 onStart() 中的某种配置检查)时尤其如此。在这种情况下,myLocationListener的onStop() 方法会在 onStart() 之前调用,这使得组件留存的时间比所需的时间要长,从而导致内次泄漏。如下:

    class MyActivity extends AppCompatActivity {
   
        private MyLocationListener myLocationListener;

        public void onCreate(...) {
   
            myLocationListener = new MyLocationListener(this, location -> {
   
                // 更新 UI
            });
        }

        @Override
        public void onStart() {
   
            super.onStart();
            Util.checkUserStatus(result -> {
   
                //如果checkUserStatus耗时较长,在activity停止后才回调,那么myLocationListener启动后就没办法走stop()方法了,
                //又因为myLocationListener持有activity,所以会造成内存泄漏。
                if (result) {
   
                    myLocationListener.start();
                }
            });
        }

        @Override
        public void onStop() {
   
            super.onStop();
            myLocationListener.stop();
        }
    }
    

即2个问题点:

  • activity的生命周期内有大量管理组件的代码,难以维护。
  • 无法保证组件会在 Activity/Fragment停止后不执行启动

Lifecycle库 则可以 以弹性和隔离的方式解决这些问题。

2.2 Lifecycle的使用

Lifecycle是一个库,也包含Lifecycle这样一个类,Lifecycle类 用于存储有关组件(如 Activity 或 Fragment)的生命周期状态的信息,并允许其他对象观察此状态。

2.2.1 引入依赖

1、非androidX项目 引入:

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

添加这一句代码就依赖了如下的库:

2、androidX项目 引入:

如果项目已经依赖了AndroidX:

implementation 'androidx.appcompat:appcompat:1.2.0'

那么我们就可以使用Lifecycle库了,因为appcompat依赖了androidx.fragment,而androidx.fragment下依赖了ViewModel和 LiveData,LiveData内部又依赖了Lifecycle。

如果想要单独引入依赖,则如下:

在项目根目录的build.gradle添加 google() 代码库,然后app的build.gradle引入依赖,官方给出的依赖如下:

//根目录的 build.gradle
    repositories {
   
        google()
        ...
    }

//app的build.gradle
    dependencies {
   
        def lifecycle_version = "2.2.0"
        def arch_version = "2.1.0"

        // ViewModel
        implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
        // LiveData
        implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
        // 只有Lifecycles (不带 ViewModel or LiveData)
        implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
    
        // Saved state module for ViewModel
        implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"

        // lifecycle注解处理器
        annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
        // 替换 - 如果使用Java8,就用这个替换上面的lifecycle-compiler
        implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"

	//以下按需引入
        // 可选 - 帮助实现Service的LifecycleOwner
        implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
        // 可选 - ProcessLifecycleOwner给整个 app进程 提供一个lifecycle
        implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
        // 可选 - ReactiveStreams support for LiveData
        implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version"
        // 可选 - Test helpers for LiveData
        testImplementation "androidx.arch.core:core-testing:$arch_version"
    }
    

看着有很多,实际上如果只使用Lifecycle,只需要引入lifecycle-runtime即可。但通常都是和 ViewModel、 LiveData 配套使用的,所以lifecycle-viewmodel、lifecycle-livedata 一般也会引入。

另外,lifecycle-process是给整个app进程提供一个lifecycle,会面也会提到。

2.2.2 使用方法

Lifecycle的使用很简单:

  • 1、生命周期拥有者 使用getLifecycle()获取Lifecycle实例,然后代用addObserve()添加观察者;
  • 2、观察者实现LifecycleObserver,方法上使用OnLifecycleEvent注解关注对应生命周期,生命周期触发时就会执行对应方法;
2.2.2.1 基本使用

在Activity(或Fragment)中 一般用法如下:

public class LifecycleTestActivity extends AppCompatActivity {
   

    private String TAG = "Lifecycle_Test";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lifecycle_test);
        //Lifecycle 生命周期
        getLifecycle().addObserver(new MyObserver());
        Log.i(TAG, "onCreate: ");
    }
    @Override
    protected void onResume() {
   
        super.onResume();
        Log.i(TAG, "onResume: ");
    }
    @Override
    protected void onPause() {
   
        super.onPause();
        Log.i(TAG, "onPause: ");
    }
}

Activity(或Fragment)是生命周期的拥有者,通过getLifecycle()方法获取到生命周期Lifecycle对象,Lifecycle对象使用addObserver方法 给自己添加观察者,即MyObserver对象。当Lifecycle的生命周期发生变化时,MyObserver就可以感知到。

MyObserver是如何使用生命周期的呢?看下MyObserver的实现:

public class MyObserver implements LifecycleObserver {
   

    private String TAG = "Lifecycle_Test";
    
    @OnLifecycleEvent(value = Lifecycle.Event.ON_RESUME)
    public void connect(){
   
        Log.i(TAG, "connect: ");
    }

    @OnLifecycleEvent(value = Lifecycle.Event.ON_PAUSE)
    public void disConnect(){
   
        Log.i(TAG, "disConnect: ");
    }
}

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

我们打开LifecycleTestActivity 然后退出,日志打印如下:

2020-11-09 17:25:40.601 4822-4822/com.hfy.androidlearning I/Lifecycle_Test: onCreate: 

2020-11-09 17:25:40.605 4822-4822/com.hfy.androidlearning I/Lifecycle_Test: onResume: 
2020-11-09 17:25:40.605 4822-4822/com.hfy.androidlearning I/Lifecycle_Test: connect: 

2020-11-09 17:25:51.841 4822-4822/com.hfy.androidlearning I/Lifecycle_Test: disConnect: 
2020-11-09 17:25:51.841 4822-4822/com.hfy.androidlearning I/Lifecycle_Test: onPause: 

可见MyObserver的方法 确实是在对应关注的生命周期触发时调用。 当然注解中的value你也写成其它 你关注的任何一个生命周期,例如Lifecycle.Event.ON_DESTROY。

2.2.2.2 MVP架构中的使用

如果是 在MVP架构中,那么就可以把presenter作为观察者:

public class LifecycleTestActivity extends AppCompatActivity implements IView {
   
    private String TAG = "Lifecycle_Test";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lifecycle_test);
        //Lifecycle 生命周期
//        getLifecycle().addObserver(new MyObserver());

        //MVP中使用Lifecycle
        getLifecycle().addObserver(new MyPresenter(this));
        Log.i(TAG</
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值