Android: 彻底搞懂Lifecycle——使用篇

news2025/7/18 16:10:35

系列文章目录

第一章 Android: 彻底搞懂Lifecycle——使用篇
第二章 Android: 彻底搞懂Lifcycle——原理篇


文章目录

  • 系列文章目录
  • 前言
  • 一、Lifecycle是什么?
    • 1. 应用场景
    • 2. 示例
  • 二、Lifecycle使用
    • 1. 泳(用)裤(库)第一步是什么?——先引入
    • 2. Lifecycle类
    • 3. LifecycleOwner接口
      • 3.1. 自定义类实现LifecycleOwner接口
  • 总结


前言

你真的了解lifecycle吗?本文的目标就是要“打破砂锅问到底”,带你真真切切了解它。
lifecycle生命周期


一、Lifecycle是什么?

lifecycle 是属于Android Jetpack(官方开发工具包)—— Architecture(架构组件)中的一员。

【官方介绍】构建生命周期感知型组件,这些组件可以根据 Activity 或 Fragment 的当前生命周期状态调整行为。

【白话】lifecycle可以和Activity或Fragment生命周期绑定,方便我们做一些跟生命周期相关的业务逻辑。

1. 应用场景

  • 控制视频缓冲的开始与停止:启动App的时候可以更快的开始缓冲视频,App销毁时停止缓冲。
  • 开始和停止网络连接:应用位于前台时可能需要实时传输数据,并在应用进入后台时自动暂停。
  • 控制页面动画的启动与停止:动画在页面可见时进行播放,不可见时停止。

2. 示例

为了方便李(理)姐(解),下面直接用伪代码写了。

class MainActivity: AppCompatActivity{
	/**网络监听器*/
	val mNet = NetListener()
	/**视频播放器*/
	val mPlayer = VideoPlayer()
	
	override fun onStart(){
		mNet.connect()// 网络开始连接
		mPlayer.startCache()// 视频开始缓冲
		耗时任务()
		// 其他业务逻辑...
	}
	
	override fun onStop(){
		mNet.cancel()// 网络断开
		mPlayer.releaseCache()// 视频释放缓存
		// 其他业务逻辑...
	}
}

这是很常见的写法,我们在生命周期的回调方法中做了很多事情,一旦代码多了后,是很难维护的。

另外,在页面停止时,其他生命周期(如onStart)有耗时任务,这时有可能onStop先结束,而耗时的组件,还存在。

随着业务复杂,也容易出bug, 让本不富裕的家庭,雪上+霜🥲,这就需要本文的主角Lifecycle来感知生命周期的变化,解耦出去这些逻辑,并自动在适当的生命周期内执行。

题外话:如果不用这个库 我们可以在onStart() onStop()回调方法中处理这些逻辑,也能达到同样的效果,但你有没有想过,一旦在这些方法中处理逻辑多了,耦合度也就严重了,我们开发中用的一些架构模式,从MVC, MVP到MVVM,再到现在的MVI,这一切的演变为了什么?它们都有一个共同的目的——解耦。随着APP越来越庞大,功能越来越多,业务逻辑也越来越复杂,我们需要让我们的程序结构更清晰,更简洁。最佳的做法就是,把逻辑抽离出来进行解耦,Activity,Fragment它们是界面控制器,只负责界面的变化,业务逻辑交给其他层来处理。

【疑问】只能和Activity、Fragment绑定? 能绑Service、Application吗?
——咱们带着问题找答案…

创作此时的最新稳定版是:lifecycle-* 2.4.1

二、Lifecycle使用

1. 泳(用)裤(库)第一步是什么?——先引入

咱们先看看可以引用哪些?

    dependencies {
        def lifecycle_version = "2.5.0-rc01"
        def arch_version = "2.1.0"

        // ViewModel
        // ViewModel模块(普通版),用在普通xml写的页面上的,以生命周期的方式管理界面相关的数据。
        implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
        // ViewModel utilities for Compose
        // 这个也是ViewModel模块(Compose版),只不过它是用在Compose页面的。
        implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
        // LiveData
        // livedata与lifecycle 有啥关系?
        // LiveData是在lifecycle基础上出来的,用于观察数据的变化,来及时更新UI界面,也就是“观察者模式”,它与“Observable”区别是,LiveData是会感知生命周期的;
        implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
        // Lifecycles only (without ViewModel or LiveData)
        // 只有Lifecycle,不包含VM 和 LiveData
        implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"

        // Saved state module for ViewModel
        // 使ViewModel支持保存状态。无论配置变化时,还是程序意外关闭时,当用到onSaveInstanceState()保存数据和恢复数据时,就可引入下面库,让这些操作在ViewModel内完成。
        implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"

        // Annotation processor
        // 注解处理器
        kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
        // alternately - if using Java8, use the following instead of lifecycle-compiler
        // 替代——如果使用Java8,请使用以下替代生命周期编译器
        // 最新版的Android Studio 2021.2.1 默认是用Java 11了,这条可不用。
        implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"

        // optional - helpers for implementing LifecycleOwner in a Service
        // 可选-用于在Service中实现LifecycleOwner
        implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"

        // optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
        // 可选-ProcessLifecycleOwner为整个应用程序进程提供生命周期
        implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"

        // optional - ReactiveStreams support for LiveData
        // 可选-使LiveData支持ReactiveStreams, ReactiveStreams是什么??
        // ReactiveStreams(反应式流) 本质上是对数据流或某种变化所作出的反应,但是这个变化什么时候发生是未知的,所以他是一种基于异步、回调的方式在处理问题。
        implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"

        // optional - Test helpers for LiveData
        // 可选-LiveData的测试帮助程序。
        testImplementation "androidx.arch.core:core-testing:$arch_version"
    }
    

现在知道答案了吧,除了Activity和Fragment外,还可以绑定Service和Application的生命周期。只要引入支持相关的可选库即可;官方提到最多的是Activity和Fragment,是因为平时主要用于这两个组件;其实只要有生命周期的组件都可以跟它绑定。而在Android中大多数的组件都是有生命周期的。

2. Lifecycle类

Lifecycle是一个抽象类,用来存储生命周期状态的;
跟踪生命周期的流程如下:
请添加图片描述
这是从某个State(状态)发生Event(事件)时,就会变为另一个状态;
现在我们想观察Activity的生命周期变化,应该怎么做呢?
首先需要继承DefaultLifecycleObserver 写个自定义的观察者类

class MyObserver : DefaultLifecycleObserver {
    override fun onResume(owner: LifecycleOwner) {
        // 执行业务逻辑
    }

    override fun onPause(owner: LifecycleOwner) {
        // 执行业务逻辑
    }
    ...
}

然后在Activity中向生命周期添加观察者

class MainActivity: AppCompatActivity{
	@Override
	fun onCreate(){
		getLifecycle().addObserver(MyObserver())
	}
}

这里有getLifecycle()这个方法,是因为在支持库 26.1.0+以上高版本中的 Fragment 和 Activity 已实现 LifecycleOwner 接口。LifecycleOwner是什么?

3. LifecycleOwner接口

LifecycleOwner接口只有一个方法getLifecycle(),返回的是Lifecycle对象。实现了这个接口,就表示这个类是具有生命周期的。

注意:你如果想管理整个APP进程的生命周期,则需要用ProcessLifecycleOwner类

3.1. 自定义类实现LifecycleOwner接口

除了Activity和Fragment组件已经默认实现了此接口外,我们也可以自定义一个类让它具有生命周期,需要使用Lifecycle的实现类LifecycleRegistry来记录状态。
【示例】

class MyObject : LifecycleOwner {
    private lateinit var mLR: LifecycleRegistry

    fun onCreate {
        mLR = LifecycleRegistry(this)
        // 设置此时状态
        mLR.markState(Lifecycle.State.CREATED)
    }

    fun onStart() {
    	// 设置此时状态
        mLR.markState(Lifecycle.State.STARTED)
    }

	/** 返回生命周期实例 */
    override fun getLifecycle(): Lifecycle = mLR
}

总结

Lifecycle的基本用法就是这样,平时直接用它的情况可能比较少,但它是ViewModel、LiveData这些常用组件背后的核心,保证数据对象不会发生内存泄露。

下一篇
第二章 Android: 彻底搞懂Lifcycle——原理篇

如果觉得本文易懂,有帮助的话,可以动动小手,点个赞啥的支持一下,你的支持是对我创作最大的谷(鼓)粒(励)儿!👍🏻

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/406302.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PyQt5(一) PyQt5安装及配置,从文件夹读取图片并显示,模拟生成素描图像

目录 一、环境配置 1.1 安装PyQt5 1.2 安装Qt工具包 1.3 配置环境变量 1.4 测试PyQt5 1.5 配置PyCharm 二、QtDesigner 窗口简单介绍 2.1 初始界面 2.2 控件介绍 三、相关函数 3.1 读取文件函数 3.1.1 打开本地图片 3.1.2 保存图片到本地 3.1.3 打开文件夹 3.1.4 打…

微信小程序|基于小程序+C#制作一个考试答题小程序

基于小程序+C#制作一个考试答题小程序打破传统线下考试答题的边界线问题,使考试不用再局限与某个统一的场所,只要有设备,哪里都能考试。 一、小程序

【动态规划】最长上升子序列、最大子数组和题解及代码实现

Halo,这里是Ppeua。平时主要更新C语言,C,数据结构算法......感兴趣就关注我吧!你定不会失望。 🌈个人主页:主页链接 🌈算法专栏:专栏链接 我会一直往里填充内容哒! &…

功能测试用例多次录制后,我丢掉了selenium,选择龙测AI-TestOps云平台

目录一、如何使用龙测AI-TestOps云平台1、进入龙测AI-TestOps云平台2、新建项目3、新建流程图4、创建任务5、查看任务状态6、查看报告、图片7、下载流程图、测试报告、excel用例二、龙测AI-TestOps云平台AI功能介绍1、NLP2、视频AI转流程图三、总结功能测试用例多次录制后&…

写着简单跑得又快的数据库语言 SPL

数据库语言的目标SQL为什么不行SPL为什么能行 数据库语言的目标 要说清这个目标,先要理解数据库是做什么的。 数据库这个软件,名字中有个“库”字,会让人觉得它主要是为了存储的。其实不然,数据库实现的重要功能有两条&#xf…

【微信小程序】按钮还能这样用?

目录 🍓button 按钮的基本使用 🍉各种神奇的按钮 🍓button 按钮的基本使用 按钮组件 功能比 HTML 中的 button 按钮丰富 通过 open-type 属性可以调用微信提供的各种功能(客服、转发、获取用户授权、获取用户信息等)…

占有统治地位的Transformer究竟是什么

讲个有趣的小故事我高二那年从乙班考入了甲班,对于那时的我 偏科英语最高只有108班级平均英语成绩125暴躁难为人女英语老师,使我上英语课时战战兢兢。英语老师很时尚,喜欢搞花里胡哨的词语让我们放松,也很尊重我虽然暴躁但维护着我…

前端系列——vue2+高德地图web端开发(使用和引入)

vue2高德地图web端开发(使用和引入)前言基础准备工作高德地图的个人开发者注册高德api网址1.点击进行注册2.注册完之后进入控制台3.创建新应用4.添加高德 2.0 新增创建vue2的项目npm 引入高德官方文档1.安装2.进入项目3. NPM 方式安装使用 Loader4.在com…

【RabbitMQ】什么是RabbitMQ?RabbitMQ有什么用?应用场景有那些?

目录 一、什么是RabbitMQ? 二、RabbitMQ是干什么的? 三、RabbitMQ的常见作用有那些? 四、RabbitMQ的应用场景有那些? 场景一:用户订单,库存处理。【服务间解耦】 场景二:用户注册&#xf…

javaScript实现倒计时功能

目录 一、主要思路 二、css样式 三、html代码 四、js内容 五、完整代码展示 六、效果展示 一、主要思路 1.通过内置时间函数实例化日期对象获取当前时间 new Date。 2.因为时间无法减去时间,有可能生成负数,所以采用时间戳的方法得到毫秒数形式的…

(完整版)2022大厂Java八股文面试题库|附答案

Java基础 说下面向对象四大特性Java语言有些特点什么是Java程序的主类?应用程序和小程序的主类有何不同?访问修饰符public,private,protected,以及不写(默认)时的区别?float f3.4;是否正确?Java有没有goto…

Spring Boot(四):Spring Boot启动原理分析

文章目录 Spring Boot启动原理分析 一、依赖导入原理 二、Spring Boot包扫描原理 三、Spring Boot自动配置原理 Spring Boot启动原理分析 一、依赖导入原理 父项目版本控制 ctrl 点击spring-boot-starter-parent进入 继续点击,进入spring-boot-dependencies…

微前端-qiankun

概念 使用框架:qiankun 介绍: qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。 qiankun官网:Go 当使用 iframe 整合系统时,假设我们有系统 A, 当我们…

MySQL+Navicat安装配置教程(超级详细、保姆级)

MySQLNavicat安装配置教程(超级详细、保姆级)一、 下载MySQL1. 选择想要安装的版本,点击Download下载二、安装MySQL1. 选择设置类型2. 选择安装的产品和功能3. 先选中“MySQL Server 5.7.31” ,之后点击下方的蓝色“Advanced Opti…

Crontab表达式执行定时任务

Cron是一个Linux下的定时执行工具,可用于执行定时任务。 启动、关闭、查看Cron服务的语法: 启动:/sbin/service crond start 查看:/sbin/service crond status 停止:/sbin/service crond stop 重启:/sbin…

微信小程序 h5页面跳转小程序(超详细讲解)

h5跳转小程序 实战项目从无到完整的h5跳转小程序经验,跳转方式分为云函数跳转和开放性标签跳转。 开放性标签是针对微信里面浏览器使用的,而云函数跳转在外部以及微信里面都可以使用。 建议需要的同学先全部浏览一遍本文。内容较长较为啰嗦。 一、不…

jQuery 获取与设置 元素属性【一篇文章轻松拿下】

hello大家好呀!此篇文章带领大家熟练掌握 jQuery 的属性方面的操作,包括固有属性的获取与设置,自定义属性的获取与设置等等,走进 jQuery 的更深层次阶段 文章目录: 一:固有属性的设置与获取 prop 1.1 固有…

uniapp 中设置全局页面背景色

uniapp 中设置全局页面背景色 提示:以下是本篇文章正文内容,下面案例可供参考 未生效 : 在pages.json里面设置单页面背景色,这种是不行的,只能在页面内生效 方法1: pages.json globalStyle 中设置 backgroundColor // pages.json"globalStyle&quo…

Vue路由传参的方法和传递参数为对象时的问题

vue路由传参方法 在编写vue项目时,时常会使用路由在不同页面中传递参数,常见使用方式如下: this.$router.push({path: "/test",query: {a: 1,b: 2} }) 这样我们就传递了两个参数,在 /test 页面 就可以接收这两个参数…

【网络】https协议

🥁作者: 华丞臧. 📕​​​​专栏:【网络】 各位读者老爷如果觉得博主写的不错,请诸位多多支持(点赞收藏关注)。如果有错误的地方,欢迎在评论区指出。 推荐一款刷题网站 👉 LeetCode刷题网站 文章…