Activity的启动和结束
onCreate:创建活动。此时会把页面布局加载进内存,进入了初始状态。
onStart:开启活动。此时会把活动页面显示在屏幕上,进入了就绪状态。
onResume:恢复活动。此时活动页面进入活跃状态,能够与用户正常交互,例如允许响应用户的点击动作、允许用户输入文字等。
onPause:暂停活动。此时活动页面进入暂停状态(也就是退回就绪状态),无法与用户正常交
互。
onStop:停止活动。此时活动页面将不在屏幕上显示。
onDestroy:销毁活动。此时回收活动占用的系统资源,把页面从内存中清除掉。
onRestart:重启活动。处于停止状态的活动,若想重新开启的话,无须经历onCreate的重复创建过程,而是走onRestart的重启过程。
onNewIntent:重用已有的活动实例。
上述的生命周期方法,涉及复杂的App运行状态,更直观的活动状态切换过程如图4-2所示。


主页


跳转


返回



如果一个Activity已经启动过,并且存在当前应用的Activity任务栈中,启动模式为singleTask,singleInstance或singleTop(此时已在任务栈顶端),那么在此启动或回到这个Activity的时候,不会创建新的实例,也就是不会执行onCreate方法,而是执行onNewIntent方法。
Activity的启动模式
第一个活动跳到第二个活动,接着结束第二个活动就能返回第一个活动,可是为什么不直接返回桌面呢?
这要从Android的内核设计说起了,系统给每个正在运行的App都分配了活动栈,栈里面容纳着已经创建且尚未销毁的活动信息。
鉴于栈是一种先进后出、后进先出的数据结构,故而后面入栈的活动总是先出栈,
假设3个活动的入栈顺序为:活动A→活动B→活动C,则它们的出栈顺序将变为:活动C→活动B→活动A,
可见活动C结束之后会返回活动B,而不是返回活动A或者别的地方。假定某个App分配到的活动栈大小为3,该App先后打开两个活动,此时活动栈的变动情况如图


实际上Android允许在创建活动时指定该活动的启动模式,通过启动模式控制活动的出入栈行为。App提供了两种办法用于设置活动页面的启动模式,其一是修改AndroidManifest.xml,在指定的activity节点添加属性android:launchMode,表示本活动以哪个启动模式运行。其二是在代码中调用Intent对象的setFlags方法,表明后续打开的活动页面采用该启动标志。下面分别予以详细说明。
<activity android:name=".JumpFirstActivity" android:launchMode="standard" />

在两个活动之间交替跳转
假设活动A有个按钮,点击该按钮会跳到活动B;同时活动B也有个按钮,点击按钮会跳到活动A;从首页打开活动A之后,就点击按钮在活动A与活动B之间轮流跳转。此时活动页面的跳转流程为:首页→活动A→活动B→活动A→活动B→活动A→活动B→……多次跳转之后想回到首页,正常的话返回流程是这样的:……→活动B→活动A→活动B→活动A→活动B→活动A→首页,注意每个箭头都代表按一次返回键,
对于不允许重复返回的情况,可以设置启动标志FLAG_ACTIVITY_CLEAR_TOP,即使活动栈里面存在待跳转的活动实例,也会重新创建该活动的实例,并清除原实例上方的所有实例,保证栈中最多只有该活动的唯一实例,从而避免了无谓的重复返回。于是活动A内部的跳转代码就改成了下面这般:
package com.example.myapplication_03;import android.content.Intent;
import android.os.Bundle;
import android.view.View;import androidx.appcompat.app.AppCompatActivity;public class JumpFirstActivity extends AppCompatActivity implements View.OnClickListener {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_jump_first);findViewById(R.id.btn_jump_second).setOnClickListener(this);}@Overridepublic void onClick(View v) {// 创建一个意图对象,准备跳到指定的活动页面Intent intent = new Intent(this, JumpSecondActivity.class);// 栈中存在待跳转的活动实例时,则重新创建该活动的实例,并清除原实例上方的所有实例intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);startActivity(intent);}
}
当然活动B内部的跳转代码也要设置同样的启动标志:
package com.example.myapplication_03;import android.content.Intent;
import android.os.Bundle;
import android.view.View;import androidx.appcompat.app.AppCompatActivity;public class JumpSecondActivity extends AppCompatActivity implements View.OnClickListener {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_jump_second);findViewById(R.id.btn_jump_first).setOnClickListener(this);}@Overridepublic void onClick(View v) {// 创建一个意图对象,准备跳到指定的活动页面Intent intent = new Intent(this, JumpFirstActivity.class);// 栈中存在待跳转的活动实例时,则重新创建该活动的实例,并清除原实例上方的所有实例intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);startActivity(intent);}
}
这下两个活动的跳转代码都设置了FLAG_ACTIVITY_CLEAR_TOP,运行测试App发现多次跳转之后,每个活动仅会返回一次而已。
登录成功后不再返回登录页面
很多App第一次打开都要求用户登录,登录成功再进入App首页,如果这时按下返回键,发现并没有回到上一个登录页面,而是直接退出App了
对于回不去的登录页面情况,可以设置启动标志FLAG_ACTIVITY_CLEAR_TASK,该标志会清空当前活动栈里的所有实例。不过全部清空之后,意味着当前栈没法用了,必须另外找个活动栈才行,也就是同时设置启动标志FLAG_ACTIVITY_NEW_TASK,该标志用于开辟新任务的活动栈。于是离开登录页面的跳转代码变成下面这样:
package com.example.myapplication_03;import android.content.Intent;
import android.os.Bundle;
import android.view.View;import androidx.appcompat.app.AppCompatActivity;public class LoginInputActivity extends AppCompatActivity implements View.OnClickListener {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_login_input);findViewById(R.id.btn_jump_success).setOnClickListener(this);}@Overridepublic void onClick(View v) {// 创建一个意图对象,准备跳到指定的活动页面Intent intent = new Intent(this, LoginSuccessActivity.class);// 设置启动标志:跳转到新页面时,栈中的原有实例都被清空,同时开辟新任务的活动栈intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);}
}
默认启动模式 standard
该模式可以被设定,不在 manifest 设定时候,Activity 的默认模式就是 standard。在该模式下,启动的 Activity 会依照启动顺序被依次压入 Task 栈中:

栈顶复用模式 singleTop
在该模式下,如果栈顶 Activity 为我们要新建的 Activity(目标Activity),那么就不会重复创建新的Activity。

适合开启渠道多、多应用开启调用的 Activity,通过这种设置可以避免已经创建过的 Activity 被重复创建,多数通过动态设置使用。
栈内复用模式 singleTask
与 singleTop 模式相似,只不过 singleTop 模式是只是针对栈顶的元素,而 singleTask 模式下,如果task 栈内存在目标 Activity 实例,则将 task 内的对应 Activity 实例之上的所有 Activity 弹出栈,并将对应 Activity 置于栈顶,获得焦点

程序主界面:我们肯定不希望主界面被创建多次,而且在主界面退出的时候退出整个 App 是最好的效果。
耗费系统资源的Activity:对于那些及其耗费系统资源的 Activity,我们可以考虑将其设为 singleTask模式,减少资源耗费。
全局唯一模式 singleInstance
在该模式下,我们会为目标 Activity 创建一个新的 Task 栈,将目标 Activity 放入新的 Task,并让目标Activity获得焦点。新的 Task 有且只有这一个 Activity 实例
如果已经创建过目标 Activity 实例,则不会创建新的 Task,而是将以前创建过的 Activity 唤醒。

看一个示例,Activity3 设置为singleInstance,Activity1 和 Activity2 默认(standard),下图程序流程中,黄色的代表 Background 的Task,蓝色的代表 Foreground 的Task。返回时会先把 Foreground 的Task 中的 Activity 弹出,直到 Task 销毁,然后才将 Background的 Task 唤到前台,所以最后将Activity3 销毁之后,会直接退出应用。
(3是单独的任务栈)

动态设置启动模式
在上述所有情况,都是我们在Manifest中通过 launchMode 属性设置的,这个被称为静态设置,动态设置是通过 Java 代码设置的。通过 Intent 动态设置 Activity启动模式
intent.setFlags();
如果同时有动态和静态设置,那么动态的优先级更高。
FLAG_ACTIVITY_NEW_TASK
Intent.FLAG_ACTIVITY_NEW_TASK
此 Flag 跟 singleInstance 很相似,在给目标 Activity 设立此 Flag 后,会根据目标 Activity 的 affinity 进行匹配,如果已经存在与其affinity 相同的 task,则将目标 Activity 压入此 Task。反之没有的话,则新建一个 task,新建的 task 的 affinity 值与目标 Activity 相同,然后将目标 Activity 压入此栈。但它与 singleInstance 有不同的点,两点需要注意的地方:
新的 Task 没有说只能存放一个目标 Activity,只是说决定是否新建一个 Task,而 singleInstance模式下新的 Task 只能放置一个目标 Activity。在同一应用下,如果 Activity 都是默认的 affinity,那么此 Flag 无效,而 singleInstance 默认情况也会创建新的 Task。
FLAG_ACTIVITY_SINGLE_TOP
Intent.FLAG_ACTIVITY_SINGLE_TOP
此 Flag 与静态设置中的 singleTop 效果相同
FLAG_ACTIVITY_CLEAR_TOP
Intent.FLAG_ACTIVITY_CLEAR_TOP
当设置此 Flag 时,目标 Activity 会检查 Task 中是否存在此实例,如果没有则添加压入栈。如果有,就将位于 Task 中的对应 Activity 其上的所有 Activity 弹出栈,此时有以下两种情况:
如果同时设置 Flag_ACTIVITY_SINGLE_TOP ,则直接使用栈内的对应 Activity。
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |Intent.FLAG_ACTIVITY_SINGLE_TOP);
没有设置,则将栈内的对应 Activity 销毁重新创建。
按位或运算符运算规则:0|0=0 0|1=1 1|0=1 1|1=1
总结:参加运算的两个对象只要有一个为1,其值为1。
例如:3|5即 0000 0011| 0000 0101 = 0000 0111,因此,3|5的值得7


相关文章:

Activity的启动和结束
onCreate:创建活动。此时会把页面布局加载进内存,进入了初始状态。onStart:开启活动。此时会把活动页面显示在屏幕上,进入了就绪状态。onResume:恢复活动。此时活动页面进入活跃状态,能够与用户正常交互&am…...
利用业务逻辑+OB分布式特性优化SQL
最近某人社局核心数据库上了OB,经常出现性能问题 某人社与我司合作多年,非常信任我司在数据库的专业能力,邀请我司过去看看能否提供帮助 与OB驻场工程师合作,抓取了一天的TOP SQL,跑得慢的SQL有几十条(注意只是某一天的…...

哈希表
文章目录什么是哈希问题引入哈希函数直接定址法除留余数法 (常用、重点)哈希冲突哈希冲突的解决方法闭散列开散列unordered_map && unordered_set 封装实现哈希的应用位图布隆过滤器哈希经典面试题哈希切分位图应用布隆过滤器什么是哈希 在上一…...

基于Halcon的MLP(多层感知神经网络)分类器分类操作实例
一、介绍 人工神经网络(Artificial Neural Network,ANN)简称神经网络(Neural Network,NN)或类神经网络,是一种模仿生物神经网络的结构和功能的数学模型或计算模型,用于对函数进行估计或近似。 MLP神经网络是一种基于神经网络、动态的分类器。MLP分类器使用神经…...

VR全景博物馆,打造7*24小时的线上参访体验
导语:博物馆作为人们了解历史、文化和艺术的重要场所,现在可以通过VR全景技术来进行展览,让参观者身临其境地感受历史文化的魅力。本文将介绍博物馆VR全景的特点、优势,以及如何使用VR全景技术来丰富博物馆的展览和教育活动。什么…...
Go 数据类型
基础数据类型 类型长度(字节)默认值说明bool1falsebyte10uint8,取值范围[0,255]rune40Unicode Code Point,int32int,uint4或者8032位或64位操作系统int8,uint810-128~127,0-255int16,uint1620-32768~32767,…...

Mybatis-Plus学透?一篇足够(持续更新中)
01、Mybatis-Plus入门 一、简介 MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。如果你想对自己的项目进行技术升级,不妨尝试将mybatis换成Mybati…...
船用燃料油市场调研报告-主要企业、市场规模、份额及发展趋势
船用燃料油市场报告主要研究:市场规模: 产能、产量、销售、产值、价格、成本、利润等行业分析:原材料、市场应用、产品种类、市场需求、市场供给,下游市场分析、供应链分析等竞争分析:主要企业情况、市场份额、并购、扩…...

python趣味编程-奥赛罗游戏
在上一期我们用Python实现了一个高速公路汽车游戏的游戏,这一期我们继续使用Python实现一个简单的奥赛罗游戏,让我们开始今天的旅程吧~ 在Python中使用Turtle实现的奥赛罗游戏 在Python中使用Turtle的简单奥赛罗游戏 是一个以 Python 为程序设计语言的项…...
经典卷积模型回顾13—ResNetXt实现图像分类(matlab)
ResNetXt是ResNet的变种,在ResNet基础上引入了"split-transform-merge"的思想,旨在进一步提升模型的性能和准确率。ResNetXt模型的核心思想是通过对输入进行分组,然后对每个分组进行不同的变换,最后再将变换后的结果合并…...

Spring学习——Maven进阶
分模块开发与设计 创建模块 书写模块代码 通过maven指令安装模块到本地仓库(install指令) 在pom.xml中导入坐标执行maven的install命令将模块安装到本地maven仓库 团队内部开发可以发布模块功能到团队内部可共享的仓库中(私服) 依赖管理 依赖指当前项目运行所需…...
第23篇:基础知识-Java Switch Case
switch case 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。 switch case 语句语法格式如下: switch(expression){ case value : //语句 break; //可选 case value : //语句 break; //可选 //你可以有任意数量的…...

Go 实现多态和 参数的动态个数及动态类型
引子 go语言作为静态(编译期类型检测)强类型(手写代码进行类型转换)语言, 要想实现 动态语言的鸭子类型的调用方法,做到 一个入参是不同类型,还是有些麻烦的; 需求 希望写代码时像python一样的鸭子类型,不用管参数类型,都可以调用同一个方法;希望 入参像python一样 能够在 个…...
vue 指令
Vue 提供了很多指令,如:v-model, v-show,v-if等等,有利于应付开发时出现的各种情况。Vue 也提供了自定义指令,有利于开发者将某些通用性功能封装成一个指令,进行全局或局部注册。如:复制指令&am…...

APP违法违规收集使用个人信息合规评流程和范围
近期,工信部通报2023年第1批《侵害用户权益行为的APP通报》(总第27批),共通报46款APP(SDK),这些被责令限期整改的APP(SDK),涉及的问题主要包括3个方面&#x…...
【力扣2379】 得到 K 个黑块的最少涂色次数(c++100%)
给你一个长度为 n 下标从 0 开始的字符串 blocks ,blocks[i] 要么是 W 要么是 B ,表示第 i 块的颜色。字符 W 和 B 分别表示白色和黑色。给你一个整数 k ,表示想要 连续 黑色块的数目。每一次操作中,你可以选择一个白色块将它 涂成…...

[2.2.2]进程调度的时机、方式、切换与过程
文章目录第二章 进程管理进程调度的时机、方式、切换与过程(一)进程调度的时机(二)进程调度的方式(三)进程的切换与过程小结第二章 进程管理 进程调度的时机、方式、切换与过程 时机 什么时候需要进程调度…...
第24篇:Java包装类知识深度分析
目录 1、包装类背景 2、包装类的优点 3、包装类与基本类型关系 4、代码示例...

常见问题整理1
目录 偏差和方差 欠拟合underfitting 过拟合overfitting 梯度消失和梯度爆炸 归一化 偏差和方差 偏差:算法期望预测和真实预测之间的偏差程度。反应的是模型本身的拟合能力。 方差:度量了同等大小的训练集的变动导致学习性能的变化,刻画…...

体验Linux 块设备驱动实验(模拟块)
目录 一、块设备 二、块设备驱动框架 1、块设备的注册和注销 2、gendisk 结构体 3、block_device_operations 结构体 4、块设备 I/O 请求过程 ①、请求队列 request_queue ②、bio 结构 三、编写驱动之请求队列 1、修改makefile 2、基本的驱动框架编辑 3、添加头文…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...

【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道
文/法律实务观察组 在债务重组领域,专业机构的核心价值不仅在于减轻债务数字,更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明,合法债务优化需同步实现三重平衡: 法律刚性(债…...