Activity 有四种启动模式,分别用于不同的使用场景:
- standard
- singleTop
- singleTask
- singleInstance
下面将介绍每种启动模式的特点、使用场景以及使用方式。
Standard
这是 Android 中默认的 Activity 启动模式,每次启动一个 Activity 的时候,都会在当前的创建一个新的 Activity 实例加入到当前的活动栈栈顶。这种模式下没有 Activity 的复用功能,启动了多少次 Activity 就会创建多少个 Activity 实例,一般情况下都会使用这种方式。
SingleTop
这种模式下,如果要启动一个 Activity ,但恰巧这个 Activity 的实例正好在当前活动栈的栈顶(就是当前的 Activity),此时就满足 singleTop 的复用条件,系统不会再新建一个 Activity 实例,而是调用这个活动的onNewIntent()方法,标志复用了这个 Activity,否则,就会创建一个实例加入栈顶 。
这种启动模式,一般用于消息列表页面,登录页面等,这些页面一般都可以从外部多次打开,所以可以采用 Activity 复用,因为它们展示的东西、拥有的功能并没有什么不同,只不过是由于外部的重复启动。
一般情况下有两种方式设置一个 Activity 的启动模式,一种是直接在AndroidManifest.xml文件中 activity 标签中声明这个活动的启动模式,如下:
<activity android:name=".ui.home.MainActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.intent.action.VIEW"/>
</intent-filter>
</activity>
另一种则是在代码中启动一个 Activity 的时候,给 Intent 添加 FLAG 选择启动这个 Activity 的启动模式,如:
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
SingleTask
使用这种模式,如果要启动的 Activity 在当前的活动栈内,那么就会不断对当前的活动栈执行出栈操作,直到这个 Activity 成为栈顶,才会停止,然后调用它的onNewIntent()方法表示复用。在这种模式下的 Activity 复用异常霸道,如果自己不在栈顶,就会将所有在自己之上的 Activity 都挤出栈。
这种启动模式,可以用来完成连续退出多个连续的 Activity 的情况,比如从主页面开始打开了好几个 Activity ,那么如果能够一步回到主页面?如果不使用启动模式,就需要在应用中有一个活动管理器,可以负责多个 Activity 的退出,但是也可以很方便的使用 SingleTask 启动模式,使用这种模式打开主页面,系统就会自动完成这些 Activity 的出栈。或者这种方式也可以用来避免页面之间循环启动而浪费内存的情况,如有活动 A B ,活动 A 可以启动 B ,B 又可以启动 A ,那么这么连续启动几次之后就会有大量的 Activity 实例,如果这些实例的功能并没有不同的话,就可以使用 SingleTask 模式完成活动的复用,例如微信的聊天页面,点击用户头像进入用户主页,然后又可以点击开始聊天进入聊天界面,但是两个聊天界面的功能完全一样,此时就可以使用 SingleTask 模式,使得在已有聊天界面的情况下复用这个 Activity 。
对应的配置方法如下:
<activity android:name=".ui.home.MainActivity"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.intent.action.VIEW"/>
</intent-filter>
</activity>
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
使用代码设置的时候需要同时使用两个标志位,如果仅使用第一个 Intent.FLAG_ACTIVITY_CLEAR_TOP 的话,这个 Activity 本身也会被销毁并重新创建,加上 Intent.FLAG_ACTIVITY_SINGLE_TOP 之后,不会重新创建而是调用其onNewIntent()方法。
SingleInstance
该模式下的 Activity 只会单独的存在于一个活动栈中,当在一个 Activity 中要启动这种模式的 Activity 的时候,首先会检测所有的活动栈,判断是否有这样一个 Activity ,如果有,则将这个活动栈移到活跃状态,并调用活动的onNewIntent(),如果没有,就会重新创建一个活动栈,并在其中创建一个活动实例,另外,这个模式下的 Activity 启动一个其他的 Activity 的时候,不会将活动添加在这个栈上,而是放在上一个非 SingleInstance 活动存在的活动栈中。
也就是说,使用 SingleInstance 模式启动的 Activity ,在整个系统中是以单例的形式存在的,这种启动模式一般用于开启一个不打乱原先的活动栈的页面,如呼叫来电页面,这是一种突发性事件,也与原来的页面没有关联,类似于代码中“工具类”的存在,这就可以使用这个单例 Activity 。
配置如下:
<activity android:name=".ui.home.MainActivity"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.intent.action.VIEW"/>
</intent-filter>
</activity>
Intent intent = new Intent();
intent.setFlags(Intent.ACTIVITY_NEW_TASK);
// 这种方式会新建一个活动栈用于启动 Activity ,但并不能保证这个活动启动的其他活动不会存在于这个活动栈上
以上是常见的的四种启动模式的相关介绍,但是 Activity 的启动模式远不止如此,看 Intent 类内部的源码就可以看到,所有 FLAG_ACTIVITY_ 开头的其实都是与启动模式相关的标志,并且每种标志叠加在一起,代码设置的 FLAG 与 xml 中设置的 lanuchMode 叠加在一起,会产生不同的效果,具体的还要具体分析,本文只是就四种 lanuchMode 进行介绍。