一、Activity 的启动模式
Activity 的启动模式分为四种:standard、singleTop、singleTask、singleInstance。
1. standard 模式
系统默认的模式,每启动一个 Activity 就会创建一个实例,无论这个实例是否已经存在。这是一种典型的多实例实现,一个任务栈中可以有多个实例,每个实例也可以属于不同的任务栈。在这种模式下,谁启动了这个 Activity ,这个 Activity 就会运行在启动它的那个 Activity 所在的任务栈中,添加到栈顶。
注意:用 ApplicationContext 区启动 standard 模式的 Activity 会报错,因为非 Activity 类型的 Context (例如 ApplicationContext)没有任务栈,这时就需要加一个启动的 flag:FLAG_ACTIVITY_NEW_TASK
。
2. singleTop 模式(栈顶复用模式)
在这种模式下,如果新的 Activity 已经位于任务栈的栈顶,那么再启动这个 Activity 将不会被重新创建,同时它的 onNewIntent()
方法将被回调,通过这个方法的参数我们可以知道当前请求的信息。但是要注意的是回调这个方法的时候,Activity 的 onCreate()
、onStart()
都不会被调用,因为这个 Activity 并没有改变。如果新的 Activity 实例已经存在但不是位于栈顶,那么新 Activity 实例依然会重建。这种启动模式通常用于接收到消息后显示的界面,例如 QQ 接收到消息后弹出 Activity。
3. singleTask 模式(栈内复用模式)
这是一种单实例模式。在这种模式下,当一个具有 singleTask 模式的 Activity 的请求启动后,系统会首先寻找是否存在该 Activity 想要的任务栈(因为启动的不一定是在同一个 APP,所以要判断有没有该 Activity 想要的任务栈),如果不存在就重新创建一个任务栈,然后创建该 Activity 的实例压入栈中。如果存在所需的任务栈,就看该 Activity 是否在栈中有实例,如果有实例存在,就将该 Activity 调到栈顶,回调它的 onNewIntent()
方法,同时将它上面的所有 Activity 出栈;如果不存在该 Activity 实例,就创建该 Activity 实例,押入栈中。
这种启动模式通常用来推出整个应用:将主 Activity 设置成 singleTask 模式,然后在要退出的 Activity 中跳转到主 Activity,从而将主 Activity 之上的 Activity 都清除,然后重写主 Activity 的 onNewIntent()
方法,在方法中加入一句 finish()
,将最后一个 Activity 结束掉。
4. singleInstance 模式(单实例模式)
这是一种加强版的 singleTask 模式,它除了具有 singleTask 的所有特性外,还加强了一点:具有此种模式的 Activity 只能单独位于一个任务栈中。换句话说就是:Activity A 是 singleInstance 模式,当 A 启动后,系统会为 A 创建一个新的任务栈,然后 A 独自承包了这个任务栈,由于栈内复用的特性,后续的请求将不会创建新的 A 实例,除非这个任务栈被系统销毁了。
二、IntentFilter 的匹配规则
如果要想自定义隐式启动别的 Activity,需要给该 Activity 添加“意图过滤器 <intent-filter>
,而且必须添加 action
。
IntentFilter 的过滤信息有 action
,category(类别)
,data
。一个 Activity 可以有很多组 intent-filter
,每组 intent-filter
都可以有多个 action
,category(类别)
,data
。一个 Intent 只有完全匹配一个 Activity 中的任意一组 intent-filter,才可以启动该 Activity。
1. action 匹配规则
action
是一个字符串(区分大小写),它的匹配规则是:一个 intent-filter
中有若干个 action
,只要 Intent 中的 action
能够和这组 intent-filter
中的任意一个 action
相匹配就可以了。
PS,如果 Intent
中没有指定 action
,那么匹配失败。
2. category 匹配规则
category
是一个字符串,它的匹配规则是:Intent
中如果出现了 category
,不管出现了多少个,对于每个 category
来说,必须是一组 intent-filter
中已经定义的 category
。如果 Intent
中没有 category
,那么这个 Intent
还是可以匹配成功的,因为默认为这个 Intent
加上了 android.intent.category.DEFAULT
。所以如果我们想我们的 Activity 能够被隐式调用,记得在 Activity 的 intent-filter
中加入 android.intent.category.DEFAULT
。
3. data 匹配规则
data
的匹配规则是:intent-filter
中如果定义了 data
,那么 Intent
中必须也要定义可匹配的 data
,就是 Intent
中的 data
必须完全匹配一组 intent-filter
中的某一个 data
。这个和 action
类似。
网友评论