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、添加头文…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...
使用python进行图像处理—图像滤波(5)
图像滤波是图像处理中最基本和最重要的操作之一。它的目的是在空间域上修改图像的像素值,以达到平滑(去噪)、锐化、边缘检测等效果。滤波通常通过卷积操作实现。 5.1卷积(Convolution)原理 卷积是滤波的核心。它是一种数学运算,…...
运行vue项目报错 errors and 0 warnings potentially fixable with the `--fix` option.
报错 找到package.json文件 找到这个修改成 "lint": "eslint --fix --ext .js,.vue src" 为elsint有配置结尾换行符,最后运行:npm run lint --fix...
Windows开机自动启动中间件
WinSW(Windows Service Wrapper 是一个开源的 Windows 服务包装器,它可以帮助你将应用程序打包成系统服务,并实现开机自启动的功能。 一、下载 WinSW 下载 WinSW-x64.exe v2.12.0 (⬇️ 更多版本下载) 和 sample-minimal.xml 二、配置 WinS…...
