android 4中启动模式,Android 四大启动模式

Activity 的 LaunchMode

默认情况下,多次启动同一个 Activity 时,系统会创建多个实例并把它们一一放入任务栈中,当我们按 back 健时,这些 Activity 会一一回退。任务栈是一种“后进先出”的栈结构,即每按一下 back 健就会有一个 Activity 出栈,直到栈空为止,当栈中无任何 Activity 时,系统会回收这个任务栈。

四种启动模式:standard、singleTop、singleTask 和 singleInstance。下面介绍各种启动模式的含义及使用例子。

一、standard – 默认模式

standard:标准模式也是系统的默认模式。每次启动一个 Activity 都会重新创建一个新的实例,不管这个实例是否已经存在。这种模式下,谁启动了这个 Activity,那么这个 Activity 就运行在启动它的那个 Activity 所在的栈中。如 Activity A 启动了 Activity B(B 是标准模式),那么 B 就会进入到 A 所在的栈中。

当我们用 ApplicationContext 去启动 standard 模式的 Activity 时会报错,错误如下:

android.util.AndroidRuntimeException: Calling startActivity() from outside

of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag.

Is this really what you want?

这是因为 standard 模式的 Activity 默认会进入启动它的 Activity 所属的任务栈中,由于非 Activity 类型的 Context (如 ApplicationContext)并没有所属的任务栈,所以就出问题了。解决方法是为待启动 Activity 指定 FLAG_ACTIVITY_NEW_TASK 标记位,这样启动的时候会创建一个新的任务栈,这时待启动的 Activity 是以 singleTask 模式启动的

二、singleTop – 栈顶复用模式

singleTop 栈顶复用模式。如果新 Activity 已经位于任务栈的栈顶,那么此 Activity 不会被重新创建,同时它的 onNewIntent 方法会被调用,通过此方法的参数可以取出当前请求的信息。需要注意的是,这个 Activity 的 onCreate、onStart 不会被系统重新调用,因为它并没有发生改变。如果新 Activity 的实例已经存在但不是位于栈顶,那么新 Activity 仍然会重建。

适合接收通知启动的内容显示页面,当收到多条新闻推送时,用于展示新闻的 Activity 设置成此模式,根据传来的 Intent 数据显示不同的新闻信息,不会启动多个 Activity。

三、singleTask – 栈内复用模式

singleTask:栈内复用模式。这是一种单实例模式,在这种模式下,只要 Activity 在一个栈中存在,那么多次启动此 Activity 都不会重新创建实例,复用时会将它上面的 Activity 全部出栈,同时它的 onNewIntent 方法会被调用。这个过程存在一个任务栈匹配,因为这个模式启动时会在自己需要的任务栈中寻找实例,这个任务栈通过 taskAffinity 属性指定,如果这个任务栈不存在,则会创建这个任务栈。

taskAffinity 标识了一个 Activity 所需的任务栈的名字,默认情况下,所有 Activity 所需的任务栈的名字为应用的包名。我们可以为每个 Activity 都单独指定 TaskAffinity 属性,这个属性必须不能和包名相同,否则就相当于没有指定。TaskAffinity 属性主要和 singleTask 启动模式或者 allowTaskReparenting 属性配对使用。另外,任务栈分为前台任务栈和后台任务栈,后台任务栈中的 Activity 处于暂停状态,用户可以通过切换将后台任务栈再次调到前台。

适合作为程序入口点,例如浏览器的主界面,不管从多少个应用启动浏览器,只会启动主界面一次,其余情况都会走 onNewIntent,并且会清空主界面上的其它页面

四、singleInstance – 单实例模式

singleInstance:单实例模式。该模式除了具备 singleTask 模式的所有特性外,该模式的 Activity 只能单独的位于一个任务栈中,具有全局唯一性,即整个系统中只有这一个实例,由于栈内复用的特性,后续的请求均不会创建新的Activity实例,除非这个特殊的任务栈被销毁了。以singleInstance模式启动的Activity在整个系统中是单例的,如果在启动这样的Activiyt时,已经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例

如何指定 Activity 的启动模式?

(1)通过 AndroidMenifest 为 Activity 指定启动模式,如下所示:

android:name=".activity.protocol.ProtocolActivity"

android:launchMode="singleTask"/>

(2)通过 Intent 中设置标志位来为 Activity 指定启动模式,如下所示:

Intent intent = new Intent();

intent.setClass(MainActivity.this, SecondActivity.class);

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

startActivity(intent);

优先级上第二种优先级高于第一种,当两种同时存在时,以第二种方式为准;这两种方式的限定方式不同,第一种无法直接为 Activity 设定 FLAG_ACTIVITY_CLEAR_TOP 标识,第二种无法为 Activity 指定 singleInstance 模式。

Activity 常用 Flags

FLAG_ACTIVITY_NEW_TASK

为 Activity 指定 singleTask 启动模式,效果和在 XML 中指定该模式相同

FLAG_ACTIVITY_SINGLE_TOP

为 Activity 指定 singleTop 启动模式,效果和在 XML 中指定该模式相同

FLAG_ACTIVITY_CLEAR_TOP

具有此标记的 Activity,当它启动时,在同一个任务栈中所有位于它上面的 Activity 都要出栈

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

具有这个标记的 Activity 不会出现在历史 Activity 的列表中,在某些情况下我们不希望用户通过历史列表回到我们的 Activity 的时候这个标记比较有用。它等同于在 XML 中指定 Activity 的属性 android:excludeFromRecents="true"。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值