一般我们主activity是能显示在桌面图标上的程序入口,并且默认情况launchMode是standard模式。
一般我们使用startActivity的时候,如果启动目标activity是standard模式的话,每启动一起就会创建目前activity的实例,也就是说同一个task栈中会出现多个目标activity。
但是为什么我们的launcher应用点击一个应用图标的时候,为什么不会创建多个目标activity呢?
原因是在launcher的startActivity中,对启动的inent加入了一个flag:Intent.FLAG_ACTIVITY_NEW_TASK,这个标记的作用是:
首先会查找是否存在和被启动的Activity具有相同的亲和性的任务栈,如果有,刚直接把这个栈整体移动到前台,并保持栈中的状态不变,即栈中的activity顺序不变,如果没有,则新建一个栈来存放被启动的activity。
比如我们从launcher启动应用的入口activity A ,接着A里面启动了B,这个时候对于该应用来说,其task栈就是 AB,A在栈底。
此时我们按Home键回到了桌面(假设现在只有桌面和刚启动的应用这两个应用程序存在,桌面应用为H),现在整个回退栈是这样的ABH,AB是一个独立的task栈,H在自己的task中,并且H在当前回退栈的栈顶。(具体参考之前的文章:
从浏览器打开一个本地应用的回退栈问题)
此时,我从launcher上点击应用图标,那么将会把AB这个task整体移动到前台,现在的回退栈是这样的HAB,也就是说明明我在launcher中startActivity的是A,其实是把整个AB任务栈都调到前台了,这也符合launcher启动应用的逻辑,点击应用图标相当于我是要进入到这个应用,那么当前应用之前的状态就应该还保存下来给我继续使用。
另外,如果我的主activity的启动模式是singleTask模式的话,启动流程是这样的:
-
先找task
- 没有特别指定taskAffinity,则为当前的task
- 如果指定了taskAffinity,先在系统中查找task,如果找不到则创建一个新的task,将activity作为root放置其中.
-
启动Activity
如果第一步中的task中已经有了这个activity的实例,则将其显示(将task中该activity上层的activity都pop出任务栈),同时intent将被通过onNewIntent()发送
所以如果主activity是这种模式的话,点击应用图标,无论之前应用进入的是哪个二级或三级界面,最终都只会进入主界面,其他界面被pop出任务栈。
这种情况被用来主activity根据intent传递过来的参数,进行任务分发,启动不同的子界面。
参考文章: