本文基于http://developer.android.com/guide/components/tasks-and-back-stack.html 的学习,中文译文http://www.cnblogs.com/popapa/p/android_tasks-and-back-stack.html,大家可以多看看呆呆大侠的博客,学习起来通熟易懂。
android启动模式跟任务和任务栈是有关的,而查看activity栈,这就需要用到adb命令:adb shell dumpsys activity。另外可以通过代码获取task的id,代码如下:
public void logStack(String tag){
ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> runningTaskInfoList = am.getRunningTasks(1);
for (ActivityManager.RunningTaskInfo runningTaskInfo : runningTaskInfoList) {
Log.e(tag, "id: " + runningTaskInfo.id);
Log.e(tag,"description: " + runningTaskInfo.description);
Log.e(tag,"number of activities: " + runningTaskInfo.numActivities);
Log.e(tag,"topActivity: " + runningTaskInfo.topActivity);
Log.e(tag,"baseActivity: " + runningTaskInfo.baseActivity.toString());
}
}
使用adb shell dumpsys activity:
这里代表android.intent.action.MAIN的是MyActivity,在其上有TwoActivity、ThreeActivity,ThreeActivity在栈顶。
启动模式详解:
"standard" (默认模式)
比如,假定某个任务的回退栈中包含了根 Activity A 和 Activity B、C、D(顺序是 A-B-C-D;D 在栈顶)。 这时,传来了一个启动 Activity D 的 Intent。 如果 Activity D 的启动模式是默认的"standard",则会启动 Activity D 类的一个新实例,栈的内容变为 A-B-C-D-D。 但是,如果 Activity D 的启动模式是"singleTop",则已有的 Activity D 实例会通过 onNewIntent() 接收这个 Intent,因为该实例位于栈顶——栈中内容仍然维持 A-B-C-D 不变。 当然,如果此 Intent 是要启动 Activity B 的,则 Activity B 的一个新实例还是会被加入栈中,即使 Activity B 的启动模式是"singleTop"也是如此。
-
"singleTask"
-
系统将创建一个新的任务,并把 Activity 实例作为根成员放入其中。 但是,如果该 Activity 已经在其他任务中存在实例了,则系统会调用已有实例的
onNewIntent() 方法把 Intent 传给已有实例,而不是再创建一个新实例。 本类 Activity 同一时刻只能存在一个实例。
注意: 虽然 Activity 启动了一个新的任务,但用户仍然可以用 回退键返回前一个 Activity。
"singleInstance"
- 除了系统不会把其他 Activity 放入当前实例所在的任务之外,其他均与 "singleTask"相同。 Activity 总是它所在任务的唯一成员;它所启动的任何 Activity 都会放入其他任务中。
再举个例子,Android 的浏览器应用就把 web 浏览器 Activity 声明为总是在它自己独立的任务中打开——把 <activity> 设为singleTask模式。 这意味着,如果某个应用提交 Intent 来打开 Android 的浏览器,则其 Activity 不会被放入该应用所在的任务中。 而是或为浏览器启动一个新的任务;或者浏览器已经在后台运行,只要把任务调入前台处理新的 Intent 即可。
无论 Activity 是在一个新的任务中启动,还是位于其他已有的任务中,用户总是可以用回退键返回到前一个 Activity 中。 但是,如果启动了一个启动模式设为singleTask的 Activity,且有一个后台任务中已存在其实例的话,则这个后台任务就会整体切换到前台。 这时,当前的回退栈中就包含了这个转入前台的任务中的全部 Activity,且位置是在栈顶。 图 4 就展示了这种场景。
图 4. 启动模式为“singleTask”的 Activity 如何加入回退栈的示意。 如果 Activity 已经是在后台任务中并带有自己的回退栈,则整个后台回退栈都会被带到前台,并放入当前任务的栈顶。
注意: 利用 launchMode 属性为 Activity 设置的启动模式可以被启动 Activity 的 Intent 标志位属性所覆盖,这将在下一节中描述。
这里我是直接复制呆呆大虾博文中启动模式翻译的部分,详细请翻阅呆呆大虾的博客。
对于standard模式和singleTop模式,看字面意思就明白了,这里主要详解singleTask和singleInstance。
思路就是创建两个apk,操作activity的访问。这里新建了一个launchmode和launch2这两个工程。具体activity访问过程为:
而launch2工程中就两个activity,MyActivity和Two2Activity。
先说singleTask:
<intent-filter>
<action android:name="com.example.launchmode.kedou"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
使launch2中的Two2Activity可以跳转到OneActivity。
第一种情况,app内部跳转:
第二种情况:其他app中的Activity访问
对于singleInstance: