Android 探索APP/应用启动模式、Intent的Flag启动标志位

写在前面:Android APP有四种启动模式——》标准模式(Standard)、栈顶复用模式(SingleTop)、栈内复用模式(SingleTask)、单例模式(SingleInstance),默认就是标准模式。启动模式决定了Activity在任务栈内的存在方式,影响了Back返回键Activity返回的顺序。启动模式看起来简单,但是实际上想要控制某些Activity的返回顺序,需要结合两个部分一起实现——》一是在AndroidManifest.xml中合理指定Activity的启动模式;二是在使用Intent启动Activity时传入合理的启动Flag。好,讲了这么多其实就是想说APP启动模式最大的作用是用来控制Activity的返回顺序,它由两部分共同进行控制,控制起来比较复杂,有必要好好学一学,把它搞清楚。

  开始之前我们先来明确一下概念,就是什么是任务栈:
任务栈:一个APP的所有Activity实例是用栈来进行管理的,当我们启动一个Activity,这个Activity就会入栈处在栈顶,只有在栈顶的Activity是用户当前可见的,按Back键栈顶的Activity就会出栈,如果栈里面还有Activity就继续显示栈顶Activity,没有就直接退出APP,这就是为什么打开的Activity多了需要按多次Back键才能退出的原因。
注:1、Home键不会导致出栈操作,这也是为什么使用Recent键打开最近使用APP能接着之前的Activity页面使用的原因。2、系统中存在多个任务栈,每个APP存在至少一个任务栈,不同的APP任务栈肯定不一样。
下面从四种启动模式开始讲解。

一、标准模式(Standard)

  没在AndroidManifest.xml指定Activity的启动模式,模式就是标准模式。Standard 是 Android Activity 的默认启动模式,每次启动 Activity 时,都会创建一个新的实例,并放入当前任务栈(Task)的顶部。即使该 Activity 已经在任务栈中,也会创建一个新的实例,而不会复用已有实例。
下面画张图举个例子看一下:同一个栈里有Activity1、Activity2,多次启动Activity1。
在这里插入图片描述
可以看到每次启动Actvity1都会重新创建,没有复用之前的栈内实例。真实的栈可以使用如下adb命令查看:执行命令打印会很多,关注Task display areas in top down Z order:的相关字段即可,比如Task{ec5b36c就是一个已经存在的任务栈。

adb命令:dumpsys activity activitiesTask display areas in top down Z order:TaskDisplayArea DefaultTaskDisplayAreamPreferredTopFocusableRootTask=Task{ec5b36c #115 type=standard A=10158:com.htc.app_launch_mode U=0 visible=true mode=fullscreen translucent=false sz=2}mLastFocusedRootTask=Task{ec5b36c #115 type=standard A=10158:com.htc.app_launch_mode U=0 visible=true mode=fullscreen translucent=false sz=2}Application tokens in top down Z order:* Task{ec5b36c #115 type=standard A=10158:com.htc.app_launch_mode U=0 visible=true mode=fullscreen translucent=false sz=2}bounds=[0,0][1440,3120]* ActivityRecord{ed84d3d u0 com.htc.app_launch_mode/.MainActivity t115}* ActivityRecord{61c5b7d u0 com.htc.app_launch_mode/.MainActivity t115}* Task{6938da2 #1 type=home ?? U=0 visible=false mode=fullscreen translucent=true sz=1}bounds=[0,0][1440,3120]* Task{d8594e9 #112 type=home I=com.google.android.apps.nexuslauncher/.NexusLauncherActivity U=0 rootTaskId=1 visible=false mode=fullscreen translucent=true sz=1}bounds=[0,0][1440,3120]* ActivityRecord{92f632c u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t112}

二、栈内复用模式(SingleTask)

  SingleTask 启动模式意味着:在任务栈(Task)中只会存在一个该 Activity 的实例。如果 Activity 已经存在于任务栈中,则不会重新创建,而是复用已有实例,并调用它的 onNewIntent() 方法。复用时,该 Activity 之上的所有 Activity 都会被清除(类似“回退”操作)。
使用方式直接在AndroidManifest.xml中显示指定launchMode即可,如下所示:

        <activityandroid:name=".Activity2"android:exported="false"android:launchMode="singleTask"/><activityandroid:name=".MainActivity"android:exported="true"android:launchMode="singleTask"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>

  假设现在有5个Activity,Activity1、Activity3是栈内复用模式,用下面的图进行说明:
在这里插入图片描述

三、栈顶复用模式(SingleTop)

  这种模式的特点是——》如果 Activity 已经在栈顶,则不会新建实例,而是复用当前实例并调用 onNewIntent() 方法。如果 Activity 不在栈顶,则仍会创建新实例。不会清除任务栈中的其他 Activity,与 singleTask 不同。可以用下面这张图来做一个形象的表示:假设有两个Activity,Activity1、Activity2都是栈顶模式。
在这里插入图片描述
可以看到只有在栈顶的会被复用。

四、单例模式(SingleInstance)

  单例模式的特点——》Activity将独占一个任务栈,且APP所有的任务栈中将只存在一个Activity实例对象。
用下面这张图举个例子:假设有三个Activity,Activity1、Activity2是非单例模式,Activity3是单例模式。
在这里插入图片描述
在这里插入图片描述
通过上图可以看到,我们从Activity1开始,但是最终返回的最后一个界面却变成了Activity3,Activity3再返回就是桌面了,这就是不同的启动模式对Activity返回顺序的影响,如果业务复杂,Activity很多,四种模式混在一起用,要准确控制Activity的返回顺序就是一件比较困难的事情了。

五、Intent启动Activity附带的Flag

5.1 FLAG_ACTIVITY_NEW_TASK

  这个标志位应该是大家最熟悉的了,如下使用:

Intent intent = new Intent(this, TargetActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

  它最大的特点在于:当 Activity 不是从另一个 Activity 中启动,而是从 Service、BroadcastReceiver 或 Application 启动时,必须使用 FLAG_ACTIVITY_NEW_TASK,否则会导致报错 android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag.因为Service、BroadcastReceiver 或 Application本身是不在任务栈中运行的,不存在任务栈,必须加上FLAG_ACTIVITY_NEW_TASK去新建任务栈。当然了如果APP已经存在了任务栈,那么就不会去创建新的任务栈,而是根据Activity的启动模式合理复用或者入栈。
注意:FLAG_ACTIVITY_NEW_TASK是APP没有任务栈的时候去新建,有了的话就不会。
所以启动Activity都会加上这个Flag,不会有什么副作用,还能防止出错,属于万金油了。示意图如下:
在这里插入图片描述

5.2 FLAG_ACTIVITY_CLEAR_TASK

  这个FLAG的意思就是在启动Activity之前,清空当前启动它的任务栈,Standard、SingleTask、SingleTop三种模式完全服从FLAG_ACTIVITY_CLEAR_TASK,但是SingleInstance 却不是这样,它会影响这个FLAG的行为,具体来说分两种:1、SingleInstance的Activity启动其它模式的Activity。2、其它模式的Activity启动SingleInstance的Activity。使用起来也很简单:

Intent intent = new Intent(this, TargetActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

  下面画一张图来做个演示:三个Activity,Activity1、Activity3非单例模式,Activity2单例模式。
在这里插入图片描述
可以看到,Activity1启动Activity2对应的是非单例模式Activity启动单例模式Activity:已有任务栈Task1不会被清空,而是新建一个任务栈Task2启动单例Activity。Activity2启动Activity3对应单例模式Activity启动非单例模式Activity:Task2没有任何影响,Task1中的Activity1被清除,取而代之的是Activity3。

5.3 FLAG_ACTIVITY_MATCH_EXTERNAL

  所有的FLAG没有写完,后续会陆续补充完成。

5.4 FLAG_ACTIVITY_SINGLE_TOP

  

5.5 FLAG_ACTIVITY_MULTIPLE_TASK

  

5.6 FLAG_ACTIVITY_FORWARD_RESULT

  

5.7 FLAG_ACTIVITY_FORWARD_RESULT

  

5.8 FLAG_ACTIVITY_PREVIOUS_IS_TOP

  

5.9 FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

  

5.10 FLAG_ACTIVITY_BROUGHT_TO_FRONT

  

5.11 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

  

5.12 FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY

  

5.13 FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET

  

5.14 FLAG_ACTIVITY_NEW_DOCUMENT

  

5.15 FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET

  

5.16 FLAG_ACTIVITY_NO_USER_ACTION

  

5.17 FLAG_ACTIVITY_REORDER_TO_FRONT

  

5.18 FLAG_ACTIVITY_NO_ANIMATION

  

5.19 FLAG_ACTIVITY_TASK_ON_HOME

  

5.20 FLAG_ACTIVITY_RETAIN_IN_RECENTS

  

5.21 FLAG_ACTIVITY_LAUNCH_ADJACENT

  

六、总结

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

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

相关文章

Y9000P部署开源模型

环境信息&#xff1a; 设备&#xff1a;Y9000P GPU&#xff1a;RTX 3060 6G 系统版本&#xff1a;Ubuntu 24.04 一、下载模型 1、环境准备 1、安装工具 apt-get -y install git-lfs git lfs install apt-get install python3 python-is-python3 pip3.12 config set global.inde…

大模型入门实战 | 基于 YOLO 数据集微调 Qwen2.5-VL-3B-Instruct 的目标检测任务

大模型入门实战 | 基于 YOLO 数据集微调 Qwen2.5-VL-3B-Instruct 的目标检测任务这篇就是新手向的“保姆级”实操文。你将把 YOLO 检测数据 转成 对话式 Grounding 数据&#xff0c;用 ms-swift 做 LoRA 微调&#xff0c;再用脚本 推理 可视化。 但值得注意的是&#xff0c;一…

基于Python+MySQL实现物联网引论课程一个火警报警及应急处理系统

物联网引论课程大作业设计报告一、选题、内容及功能说明我们大作业选择的是题目三&#xff1a;一个火警报警及应急处理系统。主要需要实现四个功能&#xff1a;感知环境温度&#xff0c;当环境温度超过阈值&#xff0c;自动触发报警&#xff1a;终端 led 以固定频率闪烁&#x…

基于印染数据的可视化系统设计与实现

标题:基于印染数据的可视化系统设计与实现内容:1.摘要 随着印染行业的快速发展&#xff0c;印染数据呈现爆发式增长。为了更好地管理和分析这些数据&#xff0c;提高印染生产的效率和质量&#xff0c;本研究旨在设计并实现一个基于印染数据的可视化系统。通过收集印染生产过程中…

实验1 第一个微信小程序

实验1 第一个微信小程序一、实验目标二、实验步骤1. 自动生成小程序2. 手动创建小程序三、程序运行结果四、问题总结与体会chunk的博客地址一、实验目标 1、学习使用快速启动模板创建小程序的方法&#xff1b; 2、学习不使用模板手动创建小程序的方法。 二、实验步骤 1. 自…

(计算机网络)JWT三部分及 Signature 作用

JWT&#xff08;JSON Web Token&#xff09;是一种用于 无状态认证 的轻量级令牌&#xff0c;广泛用于分布式系统、单页应用&#xff08;SPA&#xff09;和移动端登录。JWT 结构概览JWT 由 三部分组成&#xff0c;用 . 分隔&#xff1a;xxxxx.yyyyy.zzzzz Header&#xff08;头…

LangGraph

LangGraph 是由 LangChain 团队开发的开源框架&#xff0c;专为构建​​复杂、有状态、多主体&#xff08;Multi-Agent&#xff09;的 LLM 应用​​而设计。它通过​​图结构&#xff08;Graph&#xff09;​​ 组织工作流&#xff0c;支持循环逻辑、动态分支、状态持久化和人工…

STM32物联网项目---ESP8266微信小程序结合OneNET平台MQTT实现STM32单片机远程智能控制---MQTT篇(三)

一、前言本篇文章通过发送AT指令&#xff0c;与云平台建立通讯&#xff1a;1.创建云平台2.烧录AT固件3.MQTT订阅&#xff08;本篇&#xff09;4.单片机代码编写5.微信小程序&#xff08;下载微信开发者工具即可使用&#xff09;二、AT指令集介绍AT指令是一种文本序列&#xff0…

Apache Ozone 2.0.0集群部署

单机部署参考&#xff1a;Apache Ozone 介绍与部署使用(最新版2.0.0)-CSDN博客 安装部署 官方参考&#xff1a;Documentation for Apache Ozone 准备环境 环境准备参考&#xff1a;Linux环境下Hadoop3.4.0集群部署-CSDN博客 1->4-b 参考&#xff1a;Apache Ozone 介绍与部…

【计算机网络 | 第9篇】信道的极限容量

文章目录探秘信道的极限容量&#xff1a;从奈氏准则到香农定理一、信道极限容量的基本概念&#x1f914;二、奈氏准则&#xff1a;无噪声情况下的码元速率限制&#x1f426;‍&#x1f525;&#xff08;一&#xff09;带宽与信号传输的关系&#xff08;二&#xff09;码间串扰问…

深入理解Linux iptables防火墙:从核心概念到实战应用

一、概述&#xff1a;什么是iptables&#xff1f; 在Linux系统中&#xff0c;网络安全防护的核心工具之一便是iptables。它绝非一个简单的命令&#xff0c;而是一个功能强大的用户态工具&#xff0c;与Linux内核中的netfilter框架协同工作&#xff0c;共同构建了Linux的防火墙体…

WebRTC音频QoS方法一.1(NetEQ之音频网络延时DelayManager计算补充)

一、整体简介 NetEQ计算的网络延时&#xff0c;直接影响变速算法的决策。在变速算法里面启动关键的作用。 网络延时计算需要考虑两种情况&#xff1a; 1、单纯抖动的网络延时计算&#xff0c;在UnderrunOptimizer类中实现&#xff1b; 2、在丢包乱序场景下的网络延时计算。…

实时操作系统FreeRTOS移植到STM32VGT6

一、前言 下载平台:STM32F407VGT6 代码使用平台:VSCode 编译器:arm-none-aebi-gcc 程序下载工具:STlink 批处理工具:make 移植的FreeRTOS版本:V11.2.0 其实此方法并不局限在arm-none-aebi-gcc中&#xff0c;此方法对于Keil5也是可以使用的&#xff0c; 只不过复制的一些文件不同…

从线到机:AI 与多模态交互如何重塑 B 端与 App 界面设计

当下&#xff0c;界面设计已经不再是单纯的“画屏幕”。AI 的快速发展让我们不得不重新审视&#xff1a;交互和视觉究竟会走向什么样的未来&#xff1f;无论是移动端 App&#xff0c;还是复杂的 B 端产品&#xff0c;设计的核心都在于让界面更懂用户。本文尝试从三个角度切入&a…

【智能化解决方案】大模型智能推荐选型系统方案设计

大模型智能推荐选型系统方案设计0 背景1 问题分析与定义2 模型假设与简化3 核心模型构建3.1 决策变量与参数定义3.2 目标函数3.3 约束条件4 模型求解与验证4.1 求解策略4.2 验证方法4.3 模型迭代优化5 方案实施与系统设计5.1 系统架构设计5.2 工作流程5.3 关键算法实现5.4 时序…

【Java基础】HashMap、HashTable与HashSet:区别、联系与实践指南

Java中HashMap、HashTable与HashSet的深度解析&#xff1a;区别、联系与实践指南 引言 在Java集合框架中&#xff0c;HashMap、HashTable与HashSet是最常用的哈希型数据结构。它们因高效的查找、插入与删除性能&#xff08;平均时间复杂度O(1)&#xff09;&#xff0c;广泛应用…

互联网大厂Java面试实战:核心技术栈与场景化提问解析(含Spring Boot、微服务、测试框架等)

互联网大厂Java面试实战&#xff1a;核心技术栈与场景化提问解析 本文通过模拟面试官与求职者谢飞机的对话&#xff0c;深入探讨互联网大厂Java开发的核心技术栈面试问题&#xff0c;涵盖Java SE、Spring生态、微服务、大数据等多个领域&#xff0c;结合音视频、电商、AIGC等业…

人工智能-python-深度学习-参数初始化与损失函数

文章目录参数初始化与损失函数一、参数初始化1. 固定值初始化1.1 全零初始化1.2 全1初始化1.3 任意常数初始化2. 随机初始化2.1 均匀分布初始化2.2 正态分布初始化3. Xavier初始化4. He初始化5. 总结二、损失函数1. 线性回归损失函数1.1 MAE&#xff08;Mean Absolute Error&am…

Android Glide常见问题解决方案:从图片加载到内存优化

全面总结Glide使用中的典型问题与解决方案&#xff0c;助力提升应用性能与用户体验作为Android开发中最流行的图片加载库之一&#xff0c;Glide以其简单易用的API和强大的功能深受开发者喜爱。然而&#xff0c;在实际使用过程中&#xff0c;我们往往会遇到各种问题&#xff0c;…

linux系统ollama监听0.0.0.0:11434示例

docker应用如dify访问本地主机部署的ollama&#xff0c;base_url不管配"http://localhost:11434"&#xff0c;还是"http://host_ip:11434"都会报错。这是因为1&#xff09;docker容器访问http://localhost:11434&#xff0c;其实访问的是docker容器自身的服…