Activity的启动模式

本文详细介绍了Android中Activity的四种启动模式:standard、singleTop、singleTask和singleInstance,包括它们的工作原理及如何指定启动模式。同时,还探讨了IntentFilter的匹配规则。

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

Android在默认情况下,多次启动同一个Activity的时候,系统会创建多个实例并把他们一一放入任务栈中,当按下back键,这些activity会一一回退。任务栈是一种“后进先出”的栈结构。但是现实有些需求启动一个Activity并不需要重复创建多个实例。Android目前有四种启动模式:standard,singleTop,singleTask,singleInstance.

1.standard:标准模式(默认模式),每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否存在,它的生命周期也会重新执行,谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity的任务栈中,如:Activity A启动Activity B,那么B就会进入到A所在任务栈中。注意:当用ApplicationContext去启动standard模式时,会报错,因为非Activity类型的context并没有任务栈,解决的办法为它创建一个新的任务栈。

2.singleTop:栈顶复用模式,在这种模式下,如果新的Activity已经处于栈顶,那么Activity不会重新创建,如果Activity不是位于栈顶,那么新的Activity仍然为重新创建,例如:栈内的情况是ABC,这时候如果再次启动C,那么还是ABC,如果启动B,那么这时栈内变成:ABCB。

3.singleTask:栈内复用模式,是一种单例模式。简而言之只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例。如Activity A,系统首先会寻找是否存在A的想要的任务栈,这时要看A是否在栈中有实例存在,如果不存在,就重新创建一个任务栈,然后创建A的实例后把A放到栈中。如果存在A所需的任务栈,这时要看A是否存在栈内有A的实例存在,如果实例存在,那么系统会把A调到栈顶 。比如目前任务栈S1的情况是ABC,这时候D请求启动,其所需要的任务栈为s2,由于s2和D的实均不存在,所以系统会先创建任务栈s2,然后再创建D的实例并将其入栈到S2.另外一种情况,假设D所需的任务栈为S1,那么由于S1已经存在,所以系统会直接创建D的实例并将其入栈S1。另外一种情况,D所需的任务栈是S1,并且任务栈S1的情况是ABC,根据栈内复用原则,此时D不会重新创建,系统会把D切换到栈顶,会导致D上面的Activity全部出栈。

4.singleInstance:单实例模式,这是一种加强的singleTask模式,除了具有singleTask模式的所有特性,比如A启动后,系统会为创建一个新的任务栈,然后A独自在这个新的任务栈,由于栈内复用,后续不会创建新的Acitivty....


可以有两种方法指定启动模式

1.通过AndroidMenifest  <activity  android:lauchMode="singleTask" />

2.Intent intent = new Intent()   intent.seClass(A.this,B.class) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) startActivity(intnet)

这两种方式是有区别的:

1.优先级第二种方式的优先级要高于第一种,当两种同时存在时,以第二种方式为准

2.限定范围不一样,第一种无法直接为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都要出栈

IntentFilter的匹配规则

启动Activity分为两种,显示调用和隐式调用 暂不讨论显示调用 IntentFilter中的过滤信息有action、category、data

action的匹配规则:一个过滤规则可以有多个action,只要Intent中的action能够和过滤规则中的任何一个action相同即可匹配成功,区分大小写

category的匹配规则:intent如果含有category,那么所有的category都必须和过滤规中的一个category相同,换句话说,intent如果出现category,不管有几个category,对于每个category,它必须是过滤规则中已经定义好了的category

data的匹配规则:和action类似,如果过滤规则定义好了data,那么Intent中必须也要定义匹配的data,data有两部分组成,mimeType和URI 如:<data android mimeType="image/*" />  这种规则指定媒体类型所有类型的图片 这种情况下虽然过滤规则没有指定URI,但是却有默认值 URI的默认值为content和file。如果要为Intent指定完整的data,必须调用setDataAndType方法,不能先调用setData再调用setType,因为这两个方法会清除对方的值,源码有体现。

下面例子:

<inent-filter>
  <action android:name="com.ryg.charpter_1.c/>"
 <catrgory android:name="com.ryg.category.c"/>
<data android:mimeType="text/plain"/>
</intent-filter>

对应以下匹配
Intent intent = new Intent("com.ryg.charpter_1.c");
intent.addCategory("com.ryg.category,c");
intent.setDateAndType(Uri.parse("file://abc"),"text/plain");
startActivity(intent);





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值