Android开发之生命周期(App、Activity)
在Android开发中,应用程序(App)和活动(Activity)的生命周期是非常重要的概念。它们各自都有一系列的生命周期方法,这些方法会在特定的时刻被系统自动调用,以便于开发者对应用或活动进行相应的操作。下面将详细探讨Android应用程序和活动的生命周期。
一、应用程序(App)生命周期
应用程序的生命周期从它被加载到内存开始,直到它完全从内存中卸载。这个生命周期可以被划分为以下几个阶段:
1. 启动阶段
当用户首次启动应用时,onCreate()方法被调用,这是整个生命周期的开始。在这个方法中,开发者可以完成应用的初始化工作,如加载数据、创建视图等。
2. 运行阶段
应用正在前台运行,用户与它进行交互。在这个阶段,onResume()方法被调用。在这个方法中,开发者可以恢复应用的状态,确保用户在离开应用后再次打开时能够继续之前的工作。
3. 暂停和停止阶段
当有其他应用或屏幕处于前台时,当前应用进入暂停或停止状态。这时会调用onPause()和onStop()方法。在这个阶段,开发者可以保存应用的状态或者释放一些不必要占用的资源。
4. 重新启动阶段
当用户再次点击应用图标或从后台重新启动应用时,onRestart()方法被调用。在这个方法中,开发者可以重新初始化一些资源或者重新加载数据。
5. 销毁阶段
当应用不再需要运行并且要从内存中卸载时,onDestroy()方法被调用。在这个方法中,开发者可以释放所有占用的资源,确保应用完全退出。
示例代码
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); // 初始化应用程序的代码 Log.d("MyApplication", "onCreate() is called."); } @Override public void onStart() { super.onStart(); // 启动应用程序的代码 Log.d("MyApplication", "onStart() is called."); } @Override public void onResume() { super.onResume(); // 恢复应用程序的代码 Log.d("MyApplication", "onResume() is called."); } @Override public void onPause() { super.onPause(); // 暂停应用程序的代码 Log.d("MyApplication", "onPause() is called."); } @Override public void onStop() { super.onStop(); // 停止应用程序的代码 Log.d("MyApplication", "onStop() is called."); } @Override public void onDestroy() { super.onDestroy(); // 销毁应用程序的代码 Log.d("MyApplication", "onDestroy() is called."); }
}
二、活动(Activity)生命周期
每个 Activity 都有自己的生命周期,Activity 的生命周期与 App 的生命周期是相互独立的。
Activity的生命周期与用户界面相关,它代表了一个特定的屏幕或界面。Activity的生命周期也分为几个关键阶段:

1. 创建阶段
当新的活动实例首次被创建时,onCreate()方法被调用。这是初始化视图、数据和其他资源的好时机。开发者可以在这个方法中设置布局、初始化组件等。
2. 开始阶段
在活动首次变得可见时,onStart()方法被调用。在这个方法中,开发者可以执行一些准备工作,例如检查权限等。
3. 运行阶段
活动在前台运行并与用户交互。这是onResume()方法被调用的时刻。在这个方法中,开发者可以恢复界面状态、处理用户输入等。
4. 暂停和停止阶段
当有其他活动或屏幕覆盖当前活动时,onPause()和onStop()方法被调用。在这个阶段,开发者可以保存界面状态或者释放一些不必要占用的资源。
5. 重新启动和恢复阶段
当用户返回到这个活动时,onRestart()和onResume()方法会被再次调用。在这个方法中,开发者可以重新加载数据或者恢复界面状态。
6. 销毁阶段
当活动不再需要并且要被销毁时,onDestroy()方法被调用。在这个方法中,开发者可以释放所有占用的资源,确保活动完全退出。
示例代码
public class MyActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化 Activity 的各种资源Log.d("MyActivity", "onCreate() is called."); } @Override protected void onStart() { super.onStart(); // 做一些 Activity 启动时需要做的事情,例如加载数据等Log.d("MyActivity", "onStart() is called."); } @Override protected void onResume() { super.onResume(); // 做一些 Activity 运行时需要做的事情,例如更新 UI 等Log.d("MyActivity", "onResume() is called."); } @Override protected void onPause() { super.onPause(); // 做一些 Activity 暂停时需要做的事情,例如停止更新 UI 等Log.d("MyActivity", "onPause() is called."); } @Override protected void onStop() { super.onStop(); // 做一些 Activity 停止时需要做的事情,例如释放资源等Log.d("MyActivity", "onStop() is called."); } @Override protected void onDestroy() { super.onDestroy(); // 做一些 Activity 销毁时需要做的事情,例如清除数据等Log.d("MyActivity", "onDestroy() is called."); }
}
注意:
- 在 Activity 的生命周期中,onCreate 方法只会调用一次,其他方法可能会被调用多次。
- 在 Activity 的生命周期中,onPause 方法和 onStop 方法可能会被调用多次,但它们的顺序是固定的:onPause 方法会在 onStop 方法之前调用。
- 在 Activity 的生命周期中,onDestroy 方法只会在 Activity 被销毁时调用一次。
三 在 Activity 之间导航
在应用的生命周期中,应用很可能会多次进入和退出 Activity。例如,用户可以点按设备的返回按钮,或者 Activity 可能需要启动不同的 Activity。本部分介绍了实现成功的 Activity 转换需要了解的主题。这些主题包括从另一个 Activity 启动 Activity、保存 Activity 状态,以及恢复 Activity 状态。
从一个 Activity 启动另一个 Activity
Activity 通常需要在某个时刻启动另一个 Activity。例如,当应用需要从当前屏幕移动到新屏幕时,就会出现这种需求。
根据您的 Activity 是否希望从即将启动的新 Activity 中获取返回结果,您可以使用 startActivity() 或 startActivityForResult() 方法启动新 Activity。这两种方法都需要传入一个 Intent 对象。
Intent 对象指定您要启动的具体 Activity,或描述您要执行的操作类型(系统为您选择相应的 Activity,该 Activity 甚至可以来自不同应用)。Intent 对象还可以携带由已启动的 Activity 使用的少量数据。
startActivity()
如果新启动的 Activity 不需要返回结果,当前 Activity 可以通过调用 startActivity() 方法来启动它。
在自己的应用中工作时,您通常只需启动已知 Activity。例如,以下代码段显示如何启动一个名为 SignInActivity 的 Activity。
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
您的应用可能还希望使用 Activity 中的数据执行某些操作,例如发送电子邮件、短信或状态更新。在这种情况下,您的应用自身可能不具有执行此类操作所需的 Activity,因此您可以改为利用设备上其他应用提供的 Activity 为您执行这些操作。这便是 intent 的真正价值所在。您可以创建一个 intent,对您想执行的操作进行描述,系统会从其他应用启动相应的 Activity。如果有多个 Activity 可以处理 intent,用户可以选择要使用哪一个。例如,如果您想允许用户发送电子邮件,可以创建以下 intent:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);
添加到 intent 中的 EXTRA_EMAIL extra 是一个字符串数组,其中包含电子邮件的收件人电子邮件地址。当电子邮件应用响应此 intent 时,该应用会读取 extra 中提供的字符串数组,并将该数组放入电子邮件撰写表单的“收件人”字段。在这种情况下,电子邮件应用的 Activity 会启动,并且当用户完成操作时,您的 Activity 会继续运行。
startActivityForResult()
有时,您会希望在 Activity 结束时从 Activity 中获取返回结果。例如,您可以启动一项 Activity,让用户在联系人列表中选择收件人;当 Activity 结束时,系统将返回用户选择的收件人。为此,您可以调用 startActivityForResult(Intent, int) 方法,其中整数参数会标识该调用。此标识符用于消除来自同一 Activity 的多次 startActivityForResult(Intent, int) 调用之间的歧义。这不是全局标识符,不存在与其他应用或 Activity 冲突的风险。结果通过 onActivityResult(int, int, Intent) 方法返回。
当子级 Activity 退出时,它可以调用 setResult(int) 将数据返回到其父级。子级 Activity 必须始终提供结果代码,该结果代码可以是标准结果 RESULT_CANCELED、RESULT_OK,也可以是从 RESULT_FIRST_USER 开始的任何自定义值。此外,子级 Activity 可以根据需要返回包含它所需的任何其他数据的 Intent 对象。父级 Activity 使用 onActivityResult(int, int, Intent) 方法,以及父级 Activity 最初提供的整数标识符来接收信息。
如果子级 Activity 由于任何原因(例如崩溃)而失败,父级 Activity 将收到代码为 RESULT_CANCELED 的结果。
public class MyActivity extends Activity {// ...static final int PICK_CONTACT_REQUEST = 0;public boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {// When the user center presses, let them pick a contact.startActivityForResult(new Intent(Intent.ACTION_PICK,new Uri("content://contacts")),PICK_CONTACT_REQUEST);return true;}return false;}protected void onActivityResult(int requestCode, int resultCode,Intent data) {if (requestCode == PICK_CONTACT_REQUEST) {if (resultCode == RESULT_OK) {// A contact was picked. Here we will just display it// to the user.startActivity(new Intent(Intent.ACTION_VIEW, data));}}}}
协调 Activity
当一个 Activity 启动另一个 Activity 时,它们都会经历生命周期转换。第一个 Activity 停止运行并进入“已暂停”或“已停止”状态,同时创建另一个 Activity。如果这些 Activity 共享保存到磁盘或其他位置的数据,必须要明确第一个 Activity 在创建第二个 Activity 之前并未完全停止。相反,启动第二个 Activity 的过程与停止第一个 Activity 的过程重叠。
生命周期回调的顺序已有明确定义,特别是当两个 Activity 在同一个进程(应用)中,并且其中一个要启动另一个时。以下是 Activity A 启动 Activity B 时的操作发生顺序:
- Activity A 的
onPause()方法执行。 - Activity B 的
onCreate()、onStart()和onResume()方法依次执行(Activity B 现在具有用户焦点)。 - 然后,如果 Activity A 在屏幕上不再显示,其
onStop()方法执行。
您可以利用这种可预测的生命周期回调顺序管理从一个 Activity 到另一个 Activity 的信息转换。
总结
应用程序(App)和活动(Activity)的生命周期是Android开发中的重要概念。了解这些生命周期方法可以帮助开发者更好地管理资源、优化性能并提高用户体验。通过合理地使用这些生命周期方法,开发者可以确保应用或活动在各种情况下都能够稳定、流畅地运行。在开发过程中,遵循这些生命周期方法是至关重要的,以确保应用的稳定性和性能。
参考
- Android 开发者文档 - 了解 Activity 生命周期
- 使用生命周期感知型组件处理生命周期
- Android 官方示例代码
- Android 官方培训课程
相关文章:
Android开发之生命周期(App、Activity)
在Android开发中,应用程序(App)和活动(Activity)的生命周期是非常重要的概念。它们各自都有一系列的生命周期方法,这些方法会在特定的时刻被系统自动调用,以便于开发者对应用或活动进行相应的操…...
利用html2Canvas将表格下载为html
给到我的需求是点击按钮时请求后端接口,根据后端返回的数据,生成表格,并将表格的内容直接下载为html,如下图。 平常做的下载都是后端返回二进制流,这次前端做下载那就必须把页面先画出来,因为下载下来的表格在页面上是不显示的&a…...
《Git快速入门》Git分支
1.master、origin、origin/master 区别 首先搞懂git分支的一些名称区别: master : Git 的默认分支名字。它并不是一个特殊分支、跟其它分支完全没有区别。 之所以几乎每一个仓库都有 master 分支,是因为 git init 命令默认创建它,…...
HarmonyOS应用性能与功耗云测试
性能测试 性能测试主要验证HarmonyOS应用在华为真机设备上运行的性能问题,包括启动时长、界面显示、CPU占用和内存占用。具体性能测试项的详细说明请参考性能测试标准。 性能测试支持Phone和TV设备,包格式包括Hap/App。 前提条件 已注册华为开发者帐号&a…...
【AI】人工智能本地环境集成安装
目录 1、基础安装 1.1 GPU安装 1.1.1 GPU版本支持 1.1.2 下载CUDA 1.1.3安装CUDA 1.1.4配置环境变量 1.1.5检测CUDA是否安装成功 1.2 CUDNN安装 1.2.1 下载CUDNN 1.2.2 添加配置 1.2.3验证结果 2、pytorch安装...
主流级显卡的新选择,Sparkle(撼与科技)Intel Arc A750兽人体验分享
▼前言 对于玩家而言,英特尔独显的出现不仅打破了NVIDIA与AMD双雄天下的局面,而且旗下的Arc A系列显卡还拥有不俗的做工性能以及颇具优势的价格,无论是升级或者是装新机都非常合适。如果要在Arc A系列当中选一个性能不俗,能够满足…...
BI 商业数据分析能够给企业带来什么改变?
时下,随着中国企业数据整合应用的意识不断提高,BI 商业数据分析的应用驶入飞速发展的“快车道”。BI 商业智能利用数据分析技术与业务场景联系起来,通过一系列思维方法、指标体系及工具模型来支持市场分析、产品优化、客户洞察,从…...
模式识别与机器学习-特征选择和提取
模式识别与机器学习-特征选择和提取 特征选择一些距离测度公式独立特征的选择准则一般特征的散布矩阵准则 离散K-L变换 谨以此博客作为复习期间的记录。 常见分类问题的流程,数据预处理和特征选择提取时机器学习环节中最重要的两个流程。这两个环节直接决定了最终性…...
嵌入式——RTC闹钟Alarm
开发流程 配置RTC时钟设置RTC闹钟配置RTC闹钟中断实现中断函数RTC闹钟初始化 // 闹钟外部中断 exti_flag_clear(EXTI_17); exti_init(EXTI_17,EXTI_INTERRUPT,EXTI_TRIG_RISING);// 重置闹钟 rtc_alarm_disable(RTC_ALARM0);rtc_alarm_struct ras; ras.alarm_mask = RTC_ALARM…...
【linux】线程控制
线程控制 1.创建线程2.线程终止3.线程等待4.线程分离5.对线程的简单封装 喜欢的点赞,收藏,关注一下把! 进程概念上篇文章已经讲完了,下面我们就来说说线程控制。 我们使用的接口是pthread线程库,也叫做原生线程库给我…...
Swift学习笔记第三节:Set类型
1、代码 import Foundationvar set1: Set<Int> [1, 2, 3, 4, 3] print("定义1: \(set1)") var set2 Set(1...4) print("定义2: \(set2)") print("长度: \(set2.count)") print("是否为空: \(set2.isEmpty)") set1.insert(99)…...
【前端】安装指定版本的nodejs
先安装curl sudo apt install curl以下是 Nodejs 18.x的安装,一行代码搞定 &&\ 的意思是前面的命令执行无误后,再执行后面代码 curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - &&\ sudo apt-get install -y node…...
多商户小程序开源商城源码 打造微信商城新零售网店
一款易于二次开发的商城小程序,使用php、thinkphp6、vue、element-ui和uniapp技术栈进行开发。 该商城小程序内置多商户商城和分销商城,包括小程序商城、H5商城、公众号商城、PC商城和App, 支持多种分销模式、拼团、砍价、秒杀、优惠券、活…...
云仓酒庄的品牌雷盛红酒LEESON分享干红是纯葡萄酿造的吗?
干红是一种葡萄酒的简称,全称是干型红葡萄酒。葡萄酒按含残糖量分为干型、半干型、半甜型和甜型。无论什么型的酒,只要是葡萄酒,那就是葡萄酿造的。 云仓酒庄的品牌雷盛红酒LEESON分享干红是葡萄酒的一种,而葡萄酒却不止干红一种…...
PHP函数学习总结
version_compare(比较php版本) 用法: version_compare(string $version1, string $version2, ?string $operator null): int|bool//示例 $result version_compare(PHP_VERSION, 8.0.0) > 0 ? ok : fail;echo $result;// 输出ok证明当…...
5G RedCap:轻量5G技术的新宠
嘿,大家好!今天我们将深入了解一项引领5G轻量化时代的关键技术——5G RedCap。这项技术可谓是5G发展中的一把新利器,让我们看看它是如何在5G世界中展露头角的。 5G RedCap是什么?轻量化5G技术的精髓 5G RedCap的全名是5G Reduced…...
【LeetCode 热题 HOT 100】题解笔记 —— Day04
❤ 作者主页:欢迎来到我的技术博客😎 ❀ 个人介绍:大家好,本人热衷于Java后端开发,欢迎来交流学习哦!( ̄▽ ̄)~* 🍊 如果文章对您有帮助,记得关注、点赞、收藏、…...
rust中的超时处理
rust中的超时处理 自从 tokio 1.0发布以来,rust的异步开发总算大势已定。尽管没达到标准库的速度,依然挡不住大家的热情。看编程排行榜,增加2倍的开发者。 既生瑜何生亮,感觉go就是小号的rust。 不废话了。背景:之前…...
DML语言(重点)———update
格式:update 要修改的对象 set 原来的值新值 -- 修改学员名字,带了简介 代码案例: -- 修改学员名字,带了简介 UPDATE student SET name清宸 WHERE id 1; -- 不指定条件情况下,会改动所有表! 代码案例…...
Mybatis使用详解
简介 MyBatis是一款优秀的持久层框架,它支持普通SQL查询,存储过程和高级映射。MyBatis通过简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plain Ordinary Java Object,普通的Java对象)映射成数据…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
【iOS】 Block再学习
iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...
JUC并发编程(二)Monitor/自旋/轻量级/锁膨胀/wait/notify/锁消除
目录 一 基础 1 概念 2 卖票问题 3 转账问题 二 锁机制与优化策略 0 Monitor 1 轻量级锁 2 锁膨胀 3 自旋 4 偏向锁 5 锁消除 6 wait /notify 7 sleep与wait的对比 8 join原理 一 基础 1 概念 临界区 一段代码块内如果存在对共享资源的多线程读写操作…...
ABAP设计模式之---“Tell, Don’t Ask原则”
“Tell, Don’t Ask”是一种重要的面向对象编程设计原则,它强调的是对象之间如何有效地交流和协作。 1. 什么是 Tell, Don’t Ask 原则? 这个原则的核心思想是: “告诉一个对象该做什么,而不是询问一个对象的状态再对它作出决策。…...
