说到启动模式,先介绍下android的任务栈,任务栈是一种后进先出的结构。位于栈顶的Activity处于焦点状态,当按下back按钮的时候,栈内的Activity会一个一个的出栈,并且调用其onDestory()方法。如果栈内没有Activity,那么系统就会回收这个栈,每个APP默认只有一个栈,以APP的包名来命名.
而Android就是通过使用android:launchMode="standard|singleInstance|singleTask|singleTop"这四种启动模式来控制Acivity任务栈。
具体如下:
1、standard
标准模式,每次启动Activity都会创建一个新的Activity实例,并且将其压入任务栈栈顶,而不管这个Activity是否已经存在。Activity的启动三回调(onCreate()->onStart()->onResume())都会执行。
2、singleTop
栈顶复用模式.这种模式下,如果新Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,所以它的启动三回调就不会执行,同时Activity的onNewIntent()方法会被回调.如果Activity已经存在但是不在栈顶,那么作用于standard模式一样.
举例:A(standard),B(singleTop)
A ——>B——>B : B的onNewIntent()会被调用, 栈内(A-B)
A ——>B——>A——>B :栈内(A-B-A-B)。(不在栈顶时的跳转就跟standard方式一样)
3、singleTask
栈内复用模式.创建这样的Activity的时候,系统会先确认它所需任务栈已经创建,否则先创建任务栈.然后放入Activity,如果栈中已经有一个Activity实例,那么这个Activity就会被调到栈顶,onNewIntent(),并且singleTask会清理在当前Activity上面的所有Activity.(clear top)
举例:A(standard),B(singleTask)
A ——>B——>B : B的onNewIntent()会被调用, 栈内(A-B)(跟singleTop表现一样)
A ——>B——>A——>B :B的onNewIntent()会被调用, 栈内(A-B)
应用场景:
需求说明:
如果自己的客户端处于运行状态,按下Home键后台挂起。此时如果使用微信调起自己的客户端某 个页面,不做任何处理的情况下,按下回退或者当前 Activity.finish(),页面都会停留在自己的客户端(因为自己的Application回 退栈不为空),这明显不符合逻辑的。产品的要求 是,回退必须回到微信客户端,而且要保证不杀死自己的Application.
处理方案:
设置当前 被调起Activity的属性 为:LaunchMode=""SingleTask" taskAffinity="com.tencent.mm"(com.tencent.mm 是借助于工具找到的微信包名),就是把自己的 Activity放到微信默认的Task栈里面,这样回退时就会遵循“Task只要有Activity一定 从本Task剩余Activity回退"的原 则,不会回到自己的客户端,而且也不会影响自己客户端本来的Activity和Task逻辑。
taskAffinity 属性主要和singleTask或者allowTaskReparenting属性配对使用,其他情况下无意义
4、singleInstance
设置为 singleInstance 模式的 activity 将独占一个task(感觉task可以理解为进程),独占一个task的activity与其说是activity,倒不如说是一个应用,这个应用与其他activity是独立的,它有自己的上下文activity。
举例:A(standard),B(singleInstance)
A ——>B——>B : B的onNewIntent()会被调用, 两个栈:栈A(A),栈B(B)
A ——>B——>A——>B :B的onNewIntent()会被调用, 两个栈:栈A(A-A),栈B(B)