Android启动模式

说明一下,大家看这个帖子之前对Task,有一定的了解。而且看完这个之后,最好再看看taskAffinity属性,因为在实际应用中他们一般是联合使用的。
在Android的中Activity有4种启动方式:"standard"、"singleTop"、"singleTask"、"singleInstance"。
下面就分轻重点讲讲这些启动方式。
1、standard启动方式
这种方式也是系统默认的。说的简单点,我们在使用startActivity()方法的时候,系统就会启动一个新的Activity实例,不管它先前启动没有。如果想知道具体细节可以查看这个帖子http://marshal.easymorse.com/archives/2950,我在这里就不细细讲解了。
配图说明:

2、singleTop启动方式
如果大家把standard启动方式看懂了,这个我就说一下区别,大家就明白了。如果我们要调用的Activity在Task栈顶,系统不会像在standard方式下创建一个新的实例,而是调用onNewIntent()方法,来引导intent到栈顶的实例。如果调用的Activity不在Task栈顶,系统此时调用方式与standard方式下的一模一样。
举个例子:

现在task栈元素为A-B-C-D(D在栈顶),这时候给D发一个启动intent,如果D是 “standard”的,则生成D的一个新实例,栈变为A-B-C-D-D。

如果D是singleTop的话,则不会生产D的新实例,栈状态仍为A-B-C-D

如果这时候给B发Intent的话,不管B的launchmode是”standard” 还是 “singleTop” ,都会生成B的新实例,栈状态变为A-B-C-D-B。

注意:在一个Activity处理新的intent的时候,用户不能使用Back button来返回到先前的Activity。直到新的intent到达onNewIntent()方法中后,才可以。

3、singleTask启动方式

如果已经有其他的Task并且包含Activity实例,那就直接调用那个Task的实例。(只有一个Task中会有) 而不是创建一个新的实例。重点:假如你启动一个singleTask的Activity,同时这个Activity在background task中,那么整个background task都会被调入到前台来。下面这幅图就很好的说明这个问题。

有人问如果我调用图中的Activity X,会怎样?系统会先把Activity Y销毁,然后再将Activity X放到前台。

4、singleInstance启动方式

singleInstance 新建一个Task,且在该Task中只有它的唯一一个实例。 (只有一个Task会有,且该Task中只有它)。“singleInstance”是其所在栈的唯一activity,它会每次都被重用。

总结:

standard  每次都会新建,每个Task都可以有,且每个Task都可以有多个实例(每个Task都可以有,且可以有多个)
singleTop 当前实例如果在栈顶,就不新建实例,调用其OnNewIntent。 如不在栈顶,则新建实例 (每个Task都可以有,且可以有多个,在栈顶时可复用)
singleTask 新建一个Task,如果已经有其他的Task并且包含该实例,那就直接调用那个Task的实例。(只有一个Task中会有)
singleInstance 新建一个Task,且在该Task中只有它的唯一一个实例。 (只有一个Task会有,且该Task中只有它)

intent的flag可以覆盖activity的启动模式:

FLAG_ACTIVITY_CLEAR_TOP

   例如现在的栈情况为:A B C D D此时通过intent跳转到B,如果这个intent添加FLAG_ACTIVITY_CLEAR_TOP标记,则栈情况变为:A B。如果没有添加这个标记,则栈情况将会变成:A B C D B。也就是说,如果添加了FLAG_ACTIVITY_CLEAR_TOP标记,并且目标Activity在栈中已经存在,则将会把位于该目标activity之上的activity从栈中弹出销毁。这跟上面把BLaunch mode设置成singleTask类似。

 

FLAG_ACTIVITY_NEW_TASK

   例如现在栈1的情况是:A B CC通过intent跳转到D,并且这个intent添加了FLAG_ACTIVITY_NEW_TASK标记,如果D这个ActivityManifest.xml中的声明中添加了Task affinity,并且和栈1affinity不同,系统首先会查找有没有和DTask affinity相同的task栈存在,如果有存在,将D压入那个栈,如果不存在则会新建一个Daffinity的栈将其压入。如果DTask affinity默认没有设置,或者和栈1affinity相同,则会把其压入栈1,变成:A B C D,这样就和不加FLAG_ACTIVITY_NEW_TASK标记效果是一样的了。注意如果试图从非activity的非正常途径启动一个activity,比如从一个service中启动一个activity,则intent必须要添加FLAG_ACTIVITY_NEW_TASK标记。

 

FLAG_ACTIVITY_NO_HISTORY

   例如现在栈情况为:A B CC通过intent跳转到D,这个intent添加FLAG_ACTIVITY_NO_HISTORY标志,则此时界面显示D的内容,但是它并不会压入栈中。如果按返回键,返回到C,栈的情况还是:A B C。如果此时D中又跳转到E,栈的情况变为:A B C E,此时按返回键会回到C,因为D根本就没有被压入栈中。

 FLAG_ACTIVITY_SINGLE_TOP:和上面ActivityLaunch modesingleTop类似。如果某个intent添加了这个标志,并且这个intent的目标activity就是栈顶的activity,那么将不会新建一个实例压入栈中。

 /////////////////////////////////////////////////////////////////////////////////////////////////Activity的主要属性:(在 AndroidManifest.xml<activity  android:XXX  />

allowTaskReparenting:设置成true时,和IntentFLAG_ACTIVITY_NEW_TASK标记类似。

alwaysRetainTaskStat:   如果用户长时间将某个task移入后台,则系统会将该task的栈内容弹出只剩下栈底的activity,此时用户再返回,则只能看到根activity了。如果栈底的activity的这个属性设置成true,则将阻止这一行为,从而保留所有的栈内容。

clearTaskOnLaunch:根activity的这个属性设置成true时,和上面的alwaysRetainTaskStat的属性为true情况搞好相反。

finishOnTaskLaunch:对于任何activity,如果它的这个属性设置成true,则当task被放置到后台,然后重新启动后,该activity将不存在了

补充说明,里面遗漏的东西。
用户一定要能够离开一个task,和再回到这个task。所以,"singleTask"和"singleInstance",只能用作启动Activity的属性。如果不这样,我们在启动一个singleTask的Activity之后,使用Home键到主界面,就会回不去了,因为它不代表一个应用的启动。

原文链接
http://www.eoeandroid.com/blog-531377-3446.html
Android 中,启动模式(Launch Mode)用于控制 Activity 的创建和重用方式。Android 提供了四种标准的启动模式:`standard`、`singleTop`、`singleTask` 和 `singleInstance`。它们的区别主要体现在任务栈(Task Stack)的管理方式以及实例的复用策略上。 ### standard 这是默认的启动模式。每当启动一个 `standard` 模式的 Activity 时,系统都会创建一个新的实例,并将其压入任务栈中。即使该 Activity 已经存在于任务栈中,也会创建新的实例。 ### singleTop 与 `standard` 不同,`singleTop` 模式会在启动 Activity 时检查任务栈的栈顶是否已经存在该 Activity 的实例。如果存在,则直接复用该实例;如果不存在,则创建新的实例并压入栈顶。这种模式适用于频繁打开但内容不变的界面,例如通知详情页。 ### singleTask `singleTask` 模式表示该 Activity 在整个应用中只会存在一个实例。系统会在全局任务栈中查找该 Activity 是否已经存在。如果存在,则不会创建新实例,而是将该实例之上的所有其他 Activity 出栈,并将该实例置于栈顶。这种模式适用于需要全局唯一且可能频繁跳转的界面,例如主界面或登录页。 ### singleInstance `singleInstance` 是一种特殊的单例模式,不仅在整个应用中只存在一个实例,而且该实例独立存在于一个单独的任务栈中。这意味着该 Activity 不会与其他 Activity 共享任务栈,适用于需要全局唯一并且与其他界面隔离的场景,例如全局设置界面或全局弹窗。 以下是一个简单的 `AndroidManifest.xml` 配置示例,展示如何为 Activity 指定启动模式: ```xml <activity android:name=".MainActivity" android:launchMode="singleTask"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> ``` ### 区别总结 | 启动模式 | 是否允许多个实例 | 是否共享任务栈 | 实例查找范围 | 适用场景示例 | |----------------|------------------|----------------|------------------|----------------------| | `standard` | 是 | 是 | 当前任务栈 | 默认模式,普通页面 | | `singleTop` | 否(仅栈顶复用) | 是 | 当前任务栈 | 通知详情页 | | `singleTask` | 否 | 是 | 全局任务栈 | 主界面、登录页 | | `singleInstance` | 否 | 否 | 独立任务栈 | 全局设置、弹窗 | 通过合理选择启动模式,可以优化应用的用户体验和资源管理效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值