启动模式
Android的Activity有四种启动模式都清楚,标准启动模式standard,栈顶复用singleTop,栈内复用singleTask,单实例模式singleInstance,他们都在在AndroidManifeast中使用
- standard:每次启动startActivity都会在任务栈中创建一个新的Activity实例,重新走一遍活动的生命周期,谁去启动这个新实例,这个新的实例就会创建在谁的任务栈中。非新手都知道在service中或者使用ApplicationContext去启动活动都会出异常,导致启动失败,根本原因就是因为service上下文没有对应的任务栈,所以我们就会给它加上FLAG_ACTICITY_NEW_TASK这个flag,这样就会为它创建新的任务栈,一个singleTask启动的
- singleTop:在这种模式下,如果需要启动的Activity位于当前的栈顶,那么这个Activity不会被重新创建,它的onNewIntent会被回调,如果Activity已经存在但是不在栈顶,依然会重新创建
- singleTask:这是一种单实例模式,在这种模式下,同一个栈中只会存在同一种实例,同样如果它在栈中存在也会回调onNewIntent,同时singleTask有clearTop的效果,位于它之上的实例会全部出栈
- singleInstance:这是一种加强的单实例模式,它具有singleTask所有的特性,再加上它被创建后会位于一个单独的任务栈中,这种模式的栈只有一个实例。
多次提到某个Activity所需的任务栈,什么是Activity所需的任务栈呢?从TaskAffinity这个配置参数说起,可以翻译为任务相关性,这个参数标注了一个Activity所需任务栈的名字,默认情况下,Activity的任务栈名字为包名,这个参数主要和singleTask或者allowTaskReparenting属性配对使用,其他情况下没有意义。另外任务栈分为前台任务栈和后台任务栈,后台任务栈的Activity处于暂停状态,通过切换将后台任务切换到前台。
singleTask和TaskAffinity配合使用时,它是具有该模式的Activity的目前任务栈的名字,待启动的Activity会运行到名字和TaskAffinity相同的任务栈中。
singleTask和allowTaskReparenting配合使用时,情况比较复杂了,简而言之就是A应用启动B应用的Activity C,如果Activity C的allowTaskReparenting是true,则已启动的活动C会从应用A的任务栈移动到应用B的任务栈,点开B应用不是打开主界面而是进入已启动的活动C。
另外的一种指定启动模式的方法,就是在启动的Intent中设置FLAG标志,这个的优先级是高于xml中直接指定的,同时存在以第二种为准,其次它们的范围有所限制,xml中不能使用FLAG_ACTIVITY_CLEAR_TOP,Intent中不能指定singleInstance,跟launchMode相关是哪些标志呢?
- FLAG_ACTIVITY_NEW_TASK
- FLAG_ACTIVITY_SINGLE_TOP
- FLAG_ACTIVITY_CLEAR_TASK
- FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_NEW_TASK 设计的初衷是让Activity在目标taskAffinity中启动