Activity的四种启动模式

本文详细解释了Android中Activity的四种启动模式:standard、singleTop、singleTask和singleInstance的区别及应用场景,帮助开发者理解如何通过配置文件和Intent标志来控制Activity的加载方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在熟悉Activity的四种启动模式之前,先明确task的概念:

1.  什么是Task

Task是一个逻辑的概念,用来组织完成同一个功能的Activity,即使这些Activity来自不同的Application。对于用户来说, Android 通过将多个 Activity 保存在同一个 Task 里来体现这一用户体验。简单来说,一个 Task 就是用户体验上的一个“应用”。它将相关的 Activity 组合在一起,以 stack 的方式管理。也就是说stack和task是一一对应的关系,而不是stack和application是一一对应的关系。

2.Activity加载模式的两种设置方法

 默认情况下,新启动的Activity都和启动它的人处于同一个task中,但是Android也提供了两种方法来设置Activity加载模式,从而改变默认行为,控制task:

在Android中,每一个Activity的Task模式,都是可以由Activity提供方(通过配置文件...)和Activity使用方(通过Intent中的flag信息...)进行配置和选择。当然,使用方对Activity的控制力,是限定在提供方允许的范畴内进行,提供方明令禁止的模式,使用方是不能够越界使用的。

1>  设置manifest文件中<activity>元素的属性,这些属性包括:

   taskAffinity

   launchMode

   allowTaskReparenting

   clearTaskOnLaunch

   alwaysRetainTaskState

   finishOnTaskLaunch

2>  设置start Activity()中Intent参数的FLAG,这些FLAG包括:

FLAG_ACTIVITY_NEW_TASK

FLAG_ACTIVITY_CLEAR_TOP

FLAG_ACTIVITY_SINGLE_TOP

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

FLAG_ACTIVITY_REORDER_TO_FRONT

 

两种方式的差别在于,前者在于描述自己,声明自己如何被加载;而后者则是动态的,指出我要求你如何被加载。

注意:intent中FLAG的优先级比manifest中的属性值要高。

3.  manifest中<activity>的launchMode属性

manifest文件中<activity>元素的属性设置:

<activity android:name=".ActivityA"

           android:label="ActivityA"

            android:launchMode="">

</activity>

launchMode属性有四个属性值:"standard"、"singleTop"、"singleTask"、"singleInstance"。

1>"standard"(默认值)

每次启动,系统都会在启动它的task中创建一个新的实例。

是默认的也是标准的Task模式,在没有其他因素的影响下,使用此模式的Activity,会构造一个Activity的实例,加入到调用者的Task栈中去。

注意:即使Activity在当前task中被加载,但是如果该Activity属于另一个应用,系统也会创建一个新的进程,新启动的Activity也会运行在另外的进程中。所以task应该只是逻辑上的概念。

2>"singleTop"

基本上于standard一致,仅在请求的Activity正好位于栈顶时,有所区别。此时,配置成singleTop的Activity,不再会构造新的实例加入到Task栈中,而是将新来的Intent发送到栈顶Activity中,栈顶的Activity可以通过重载onNewIntent来处理新的Intent(当然,也可以无视...)。

Startup - launch

ActivityA:====> onCreate()

ActivityA: ====>onStart()

ActivityA:====> onPostCreate()

ActivityA:====> onResume()

ActivityA:====> onPostResume()

Start - singleTop

ActivityA:====> onPause()

ActivityA:====> onNewIntent()

ActivityA:====> onResume()

 

3> "singleTask"

“singleTask”的Activity只允许存在一个实例。

默认情况下,一个新启动的Activity归属于启动它的task(即使启动者所在task的taskAffinity的和SingleTask的Activity的taskAffinity值不匹配)。

    当一个应用程序加载singleTask模式的Activity时,系统首先会检查是否存在与singleTask的taskAffinity相同的Task。

1.      如果task存在,检查是否实例化。

1)        如果没有实例化,实例化singleTask并入栈。

2)        如果已经实例化,销毁在singleTask以上的所有Activity并调用onNewIntent()。

2.      如果task不存在,那么就重新创建Task,并实例化singleTask入栈。

栈空间简易示意:A -- B -- C

 最后用startActivity(intent)从C跳到A后,由于栈空间已经存在A的实例,A上面的Activity B和C出栈(即onDestroy销毁),A置于栈顶

如果A中重写了onNewIntent(...)方法,会同时接到C跳A的intent数据

4> "singleInstance"

和"singleTask"一样,“singleInstance”的Activity只允许存在一个实例,但是"singleInstance"是所属task中的唯一activity,所有由singleInstance所启动的activity都会被放置到另外的task中启动。

所以,可以看出,与"singleTask"不同的是,当在自身应用中启动singleInstance时,系统会创建一个新的task。而启动singleTask时,系统不会创建新的task,这是因为singleInstance在task中必须是唯一的。

   当应用程序加载一个singleInstance模式的Activity时,如果没有被实例化,那么就重新创建一个Task,并实例化入栈,如果已经被实例化,那么就将singleInstance所在的task带到前台,并调用singleInstance的onNewIntent()。

1,起始Activity非singleInstance (实际跳转顺序:A -- B -- C -- A -- B -- C .....)

 

A,C位于同一栈中,taskId相同, B在另一个栈中,与他们taskId不同,此栈在B未被销毁前只能有B一个Activity(B在创建之后,onNewIntent(...)也可以接到其他Activity跳转的intent数据),整个过程中,B只创建了一次,A与C每次都创建一个实例

2,起始Activity为singleInstance(实际跳转顺序:A -- B -- C -- A -- C -- A -- C .....)

代码中第一种情况相同,但实际跳转顺序却不同,

第一次A -- B -- C 实际跳转完成之后,当从C回到A(A在创建之后,onNewIntent(...)也可以接到其他Activity跳转的intent数据)后,再从A跳B时,却跳到了C页面,依次循环,整个过程中,B只是在一开始创建时出现了一次,之后从A都是直接跳C,A当然是单实例的,但是C也只创建了一次,相当于是单实例

多次跳转按物理返回键时:

如果当前页面是A,则A销毁,出现C,接着C销毁,出现B,B销毁,应用程序结束

如果当前页面是C,则C销毁,出现B,接着B销毁,出现A,A销毁,应用程序结束

返回键的实际跳转情况属于正常,因为A的taskId, 与B,C不同,不在同一栈中.

 

 

 

转载于:https://www.cnblogs.com/wmlhj666/archive/2012/11/06/2757184.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值