Activity启动模式
Task:
Task表示“作业”或“任务”。
在android系统中,执行某个任务时可能存在多个与用户产生交互的Activity,
Task则是这些Activity的容器;
执行Task的多个Activity不一定归属于同一个应用程序。
执行Task的多个Activity中,可能有同一个Activity的多个实例
Back Stack
Task使用Back Stack保存、管理各个Activity。
Back Stack表示“回退栈”;
每个Back Stack最顶端(栈顶)的Activity被置于前台,称之为Forground Activity,即“前台Activity”。
Back Stack有压栈(Push)和出栈(Pop)的操作,且遵循“先进后出,后进先出”的原则。
Task作为一个容器,使用Back Stack保存、管理各个Activity。
用户在使用Android设备时,可以启动多个Task。
每个Task都是一个有聚合力的单元,它可以在用户启动一个新的Task或按下HOME键返回桌面时整体的被置于后台。
无论Task置于前台或后台,其Back Stack都是完整的保存的,因此,用户在执行某个Task时,
另外启动了新的Task,则原Task被置于后台,但当原Task重新置于前台时,他的Back Stack依然存在。
Activity的launchMode
launchMode表示“启动模式”。
当Activity的launchMode被配置为不同的值时,当尝试激活Activity时,可能会受影响:
当Activity的实例数量不同;
所在的Task会不同;(在Activity中通过getTaskId()可查看Task的ID)
在Back Stack中的列表不同;
在Back Stack中各Activity经历的生命周期不同;
开发人员可以在项目的AndroidMainfest.xml中配置<activity>节点的launchMode属性
Activity的4种launchMode
standard
标准模式,每次激活Activity时均在当前任务栈中创建新的实例。
singleTop
位于栈顶时唯一,如果当前Activity已位于当前任务栈的栈顶,则不会创建新的实例。
singleTask
独立于任务栈,如果该Activity的实例不存在,则创建并获得栈顶位置,如果实例已经存在,则其上方的Activity均出栈,且该Activity获得
栈顶位置
singleInstance
实例唯一,实例独占任务栈,且无论哪个任务栈共享同一个Activity实例。
taskAffinity
Affinity表示Activity的“亲属关系”;
在Androidmainfest.xml文件中,可以为每个Activity配置taskAffinity属性,表示该Activity希望进入的Task,
默认情况下,同一个应用程序中各个Activity的taskAffinity属性值均均相同,则表示使用Application的taskAffinity,
如果Application没有指定该属性,则默认为项目的包名。
在配置taskAffinity属性时,取值应参照包名的命名格式,且不应该使用下划线(_),避免应用程序在编译打包时出现问题。
情景:
singleTaskActivity的launchMode配置为singleTask;
SingleTaskActivity与激活它的Activity有相同的taskAffinity(使用默认,或显式的指定相同属性值)。
结论:
SingleTaskActivity与激活它的Activity在相同的Task中。
情景:
SingleTaskActivity的launchMode配置为singleTask;
SingleTaskActivity与激活它的Activity配置了不同的taskAffinity。
结论:
SingleTaskActivity与激活它的Activity在不同的Task中;
情景:
SingleTaskActivity的launchMode配置为singleTask;
使用另一个应用程序的Activity去激活SingleTaskActivity;
SingleTaskActivity与激活它的Activity配置了相同的taskAffinity。
结论:
SingleTaskActivity与另一个应用程序中激活它的Activity在相同的Task中。
singleInstance
实例唯一,无论哪个Task,共享同一个Activity的实例。
该Activity有独立的Task,且在Task中唯一,由该Activity激活的其他Activity归属于其他Task;
由被配置为singleInstance的Activity激活的其它Activity,会尝试放在存在“亲属”关系的Task中,如果没有匹配的Task
Task存在,则会创建新的Task存放被激活的Activity。
Activity的其他属性
allowTaskReparenting
Activity能否从启动的Task移动到存在“亲属”关系的Task(当这个Task进入到前台时)。
该属性值取值为true或false
alwaysRetainTaskState
Activity所在的Task的状态是否总是由系统来保持,即该Task可能长期被置于后台,但系统不会对其进行清理。
该属性取值为true或false,默认值是false。
clearTaskOnLaunch
当Task被置于后台,是否清除Task中除了根Activity以外的其它所有的Activity。
该属性取值为true或false;
finishOnTaskLaunch
当Activity已经启动,且其所在的Task被置于后台之后,如果Task再次回到前台,是否清除已经存在的实例。
该属性作用于单个Activity;
该属性取值为true或false,默认为false;
noHistory
当Activity被置于后台之后,是否将其从Back Stack中清除并结束。
该属性取值为true或false,默认为false;
使用Intent的Flag设置启动参数
Intent类定义了一批常量,用于配置激活Activity的相关参数:
调用Intent的setFlags()或addFlags()可以配置Intent的Flag属性。
FLAG_ACTIVITY_NEW_TASK
尝试开启新的Task,可能产生的效果:
如果当前已有Task与尝试激活的activity的TaskAffinity相同,则在该Task中直接压栈,
被激活的Activity获得栈顶位置;
如果当前没有Task与尝试激活的Activity的taskAffinity相同,则创建新的Task,且被激活的Activity获得栈顶位置。
FLAG_ACTIVITY_CLEAR_TASK
清空被激活的Activity应该归属的Task,且被激活的Activity添加到该Task中获得栈顶位置。
该FLAG应与FLAG_ACTIVITY_NEW_TASK一同使用。
FLAG_ACTIVITY_SINGLE_TOP
位于栈顶时唯一,其特性可参考将<activity>中launchMode属性配置为singleTop。
FLAG_ACTIVITY_CLEAR_TOP
清除顶部,可能产生的效果:
情景1:当Intent尝试激活的Activity的实例在Task中不存在时,创建该Activity的实例,并获得栈顶位置;
情景2:如果该Activity的实例已经存在,则清除Task中该实例之上的所有Activity,且获得栈顶位置;
情景3:在情景2的基础上,如果该Activity的launchMode属性不是singleTask或singleInstance时,该Activity
原本存在的实例也会被移除,位于栈顶的是新创建的该Activity实例。
FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
当Task被Reset时,清除该Activity及在Task中位于该Activity之上的所有Activity。
当Task被置于后台,且重新被置于前台时,则可能被Reset(由系统添加FLAG_ACTIVITY_CLEAR_RESET_TASK_IF_NEEDED),
通常通过点击应用程序图标回到前台时会Reset,而通过任务列表则不会。
Back与 Stack
激活Activity与压栈
当Activity被激活时,它在Back Stack中压栈,成为栈顶Activity,则被显示且获得焦点。
以第1次启动某个应用程序为例:
大多数的Task以HOME界面,或应用程序列表界面作为起点,当用户击应用程序图标时,Task
被创建且置于前台,系统检索到入口Activity后在Back Stack中压栈,由于Task是新创建的,则
此时Back Stack中只有一个Activity,入口Activity即是栈顶Activity也是栈底Activity,
所以入口Activity被显示且获得焦点。
当同一个Task中,出现新的Activity压栈时,或当前Task被整体的置于后台时,原Task栈顶Activity
被停止时的状态将被保存。
例如:
在某应用程序的登陆界面中,输入了用户信息,然后被来电中断,当通话结束后,原登录界面中已经输入的信息依然存在。
注意:由于系统可能因为资源不足而销毁一些Activity,所以并不能保证当Task被置于后台之后,再次回到前台时Activity的状态依然存在,因为很可能整个Activity都己经
不存在了。
Activity的销毁与出栈
当用户点击“Back”键时,栈顶的Activity出栈,一旦出栈,则该Activity被终止,且资源被回收,即销毁。
Activity的状态与Back Stack
在Back Stack中,Activity的状态可能为:
当新激活的Activity压栈,则成为栈顶Activity,该Activity处于运行态;
当用户点击“Back”键,栈顶Activity出栈,且被销毁,处于终止态;
在栈内,且不处于栈顶的Activity,可能处于暂停态、停止态、终止态。
Activity的生命周期方法
当激活Activity时:
配置为standard模式时,经历:
onCreate()->onStart()->onResume()
如果Activity已经置于前台,且不需要创建实例(例如singleTop模式、singleTask模式、singleInstance模式),则经历:
onPause()->onResume()
如果Activity已被置于后台,且不需要创建实例(例如singleTask模式、singleInstance模式),则经历:
onRestart()->onStart()->onResume()
被强制出栈的Activity都会经历onDestroy().
Task表示“作业”或“任务”。
在android系统中,执行某个任务时可能存在多个与用户产生交互的Activity,
Task则是这些Activity的容器;
执行Task的多个Activity不一定归属于同一个应用程序。
执行Task的多个Activity中,可能有同一个Activity的多个实例
Back Stack
Task使用Back Stack保存、管理各个Activity。
Back Stack表示“回退栈”;
每个Back Stack最顶端(栈顶)的Activity被置于前台,称之为Forground Activity,即“前台Activity”。
Back Stack有压栈(Push)和出栈(Pop)的操作,且遵循“先进后出,后进先出”的原则。
Task作为一个容器,使用Back Stack保存、管理各个Activity。
用户在使用Android设备时,可以启动多个Task。
每个Task都是一个有聚合力的单元,它可以在用户启动一个新的Task或按下HOME键返回桌面时整体的被置于后台。
无论Task置于前台或后台,其Back Stack都是完整的保存的,因此,用户在执行某个Task时,
另外启动了新的Task,则原Task被置于后台,但当原Task重新置于前台时,他的Back Stack依然存在。
Activity的launchMode
launchMode表示“启动模式”。
当Activity的launchMode被配置为不同的值时,当尝试激活Activity时,可能会受影响:
当Activity的实例数量不同;
所在的Task会不同;(在Activity中通过getTaskId()可查看Task的ID)
在Back Stack中的列表不同;
在Back Stack中各Activity经历的生命周期不同;
开发人员可以在项目的AndroidMainfest.xml中配置<activity>节点的launchMode属性
Activity的4种launchMode
standard
标准模式,每次激活Activity时均在当前任务栈中创建新的实例。
singleTop
位于栈顶时唯一,如果当前Activity已位于当前任务栈的栈顶,则不会创建新的实例。
singleTask
独立于任务栈,如果该Activity的实例不存在,则创建并获得栈顶位置,如果实例已经存在,则其上方的Activity均出栈,且该Activity获得
栈顶位置
singleInstance
实例唯一,实例独占任务栈,且无论哪个任务栈共享同一个Activity实例。
taskAffinity
Affinity表示Activity的“亲属关系”;
在Androidmainfest.xml文件中,可以为每个Activity配置taskAffinity属性,表示该Activity希望进入的Task,
该属性的值是字符串。
<activity
android:name=".MainActivity"
android:label="@String/app_name"
android:taskAffinity="">
默认情况下,同一个应用程序中各个Activity的taskAffinity属性值均均相同,则表示使用Application的taskAffinity,
如果Application没有指定该属性,则默认为项目的包名。
在配置taskAffinity属性时,取值应参照包名的命名格式,且不应该使用下划线(_),避免应用程序在编译打包时出现问题。
情景:
singleTaskActivity的launchMode配置为singleTask;
SingleTaskActivity与激活它的Activity有相同的taskAffinity(使用默认,或显式的指定相同属性值)。
结论:
SingleTaskActivity与激活它的Activity在相同的Task中。
情景:
SingleTaskActivity的launchMode配置为singleTask;
SingleTaskActivity与激活它的Activity配置了不同的taskAffinity。
结论:
SingleTaskActivity与激活它的Activity在不同的Task中;
情景:
SingleTaskActivity的launchMode配置为singleTask;
使用另一个应用程序的Activity去激活SingleTaskActivity;
SingleTaskActivity与激活它的Activity配置了相同的taskAffinity。
结论:
SingleTaskActivity与另一个应用程序中激活它的Activity在相同的Task中。
singleInstance
实例唯一,无论哪个Task,共享同一个Activity的实例。
该Activity有独立的Task,且在Task中唯一,由该Activity激活的其他Activity归属于其他Task;
由被配置为singleInstance的Activity激活的其它Activity,会尝试放在存在“亲属”关系的Task中,如果没有匹配的Task
Task存在,则会创建新的Task存放被激活的Activity。
Activity的其他属性
allowTaskReparenting
Activity能否从启动的Task移动到存在“亲属”关系的Task(当这个Task进入到前台时)。
该属性值取值为true或false
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:allowTaskReparenting=""
>
alwaysRetainTaskState
Activity所在的Task的状态是否总是由系统来保持,即该Task可能长期被置于后台,但系统不会对其进行清理。
该属性取值为true或false,默认值是false。
clearTaskOnLaunch
当Task被置于后台,是否清除Task中除了根Activity以外的其它所有的Activity。
该属性取值为true或false;
finishOnTaskLaunch
当Activity已经启动,且其所在的Task被置于后台之后,如果Task再次回到前台,是否清除已经存在的实例。
该属性作用于单个Activity;
该属性取值为true或false,默认为false;
noHistory
当Activity被置于后台之后,是否将其从Back Stack中清除并结束。
该属性取值为true或false,默认为false;
使用Intent的Flag设置启动参数
Intent类定义了一批常量,用于配置激活Activity的相关参数:
调用Intent的setFlags()或addFlags()可以配置Intent的Flag属性。
FLAG_ACTIVITY_NEW_TASK
尝试开启新的Task,可能产生的效果:
如果当前已有Task与尝试激活的activity的TaskAffinity相同,则在该Task中直接压栈,
被激活的Activity获得栈顶位置;
如果当前没有Task与尝试激活的Activity的taskAffinity相同,则创建新的Task,且被激活的Activity获得栈顶位置。
FLAG_ACTIVITY_CLEAR_TASK
清空被激活的Activity应该归属的Task,且被激活的Activity添加到该Task中获得栈顶位置。
该FLAG应与FLAG_ACTIVITY_NEW_TASK一同使用。
FLAG_ACTIVITY_SINGLE_TOP
位于栈顶时唯一,其特性可参考将<activity>中launchMode属性配置为singleTop。
FLAG_ACTIVITY_CLEAR_TOP
清除顶部,可能产生的效果:
情景1:当Intent尝试激活的Activity的实例在Task中不存在时,创建该Activity的实例,并获得栈顶位置;
情景2:如果该Activity的实例已经存在,则清除Task中该实例之上的所有Activity,且获得栈顶位置;
情景3:在情景2的基础上,如果该Activity的launchMode属性不是singleTask或singleInstance时,该Activity
原本存在的实例也会被移除,位于栈顶的是新创建的该Activity实例。
FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
当Task被Reset时,清除该Activity及在Task中位于该Activity之上的所有Activity。
当Task被置于后台,且重新被置于前台时,则可能被Reset(由系统添加FLAG_ACTIVITY_CLEAR_RESET_TASK_IF_NEEDED),
通常通过点击应用程序图标回到前台时会Reset,而通过任务列表则不会。
Back与 Stack
激活Activity与压栈
当Activity被激活时,它在Back Stack中压栈,成为栈顶Activity,则被显示且获得焦点。
以第1次启动某个应用程序为例:
大多数的Task以HOME界面,或应用程序列表界面作为起点,当用户击应用程序图标时,Task
被创建且置于前台,系统检索到入口Activity后在Back Stack中压栈,由于Task是新创建的,则
此时Back Stack中只有一个Activity,入口Activity即是栈顶Activity也是栈底Activity,
所以入口Activity被显示且获得焦点。
当同一个Task中,出现新的Activity压栈时,或当前Task被整体的置于后台时,原Task栈顶Activity
被停止时的状态将被保存。
例如:
在某应用程序的登陆界面中,输入了用户信息,然后被来电中断,当通话结束后,原登录界面中已经输入的信息依然存在。
注意:由于系统可能因为资源不足而销毁一些Activity,所以并不能保证当Task被置于后台之后,再次回到前台时Activity的状态依然存在,因为很可能整个Activity都己经
不存在了。
Activity的销毁与出栈
当用户点击“Back”键时,栈顶的Activity出栈,一旦出栈,则该Activity被终止,且资源被回收,即销毁。
Activity的状态与Back Stack
在Back Stack中,Activity的状态可能为:
当新激活的Activity压栈,则成为栈顶Activity,该Activity处于运行态;
当用户点击“Back”键,栈顶Activity出栈,且被销毁,处于终止态;
在栈内,且不处于栈顶的Activity,可能处于暂停态、停止态、终止态。
Activity的生命周期方法
当激活Activity时:
配置为standard模式时,经历:
onCreate()->onStart()->onResume()
如果Activity已经置于前台,且不需要创建实例(例如singleTop模式、singleTask模式、singleInstance模式),则经历:
onPause()->onResume()
如果Activity已被置于后台,且不需要创建实例(例如singleTask模式、singleInstance模式),则经历:
onRestart()->onStart()->onResume()
被强制出栈的Activity都会经历onDestroy().
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理