一、前言
在初学Android的时候,几乎所有的学习资料都会提到Activity有四种启动模式:
- standard
- singleTop
- singTask
- singleInstance
而提到这四种启动方式的差异,必然要提到一个重要的概念Activity的Task任务栈,我们需要明确的一点是Activity从静态上来看它属于某一个Application,但Task并不对应某一个Application,Task是系统层级的调度结构,即一个Task中可以有多个Application的Activity,或一个Application中的不同Activity会存在于多个Task中。
我们可以在手机上直观的看到当前有哪些Task:
或者通过命令查看:
adb shell dumpsys activity activities | sed -En -e '/Stack #/p' -e '/Running activities/,/Run #0/p'
二、四种启动模式差异
四种启动模式的差异主要在于创建新的Activity实例时不同的复用逻辑。
1.standard 默认模式
系统在启动Activity的任务中创建Activity的新实例并向其传送intent。Activity可以多次实例化,不管这个Activity实例是否已存在,而每个实例均可属于不同的任务栈,并且一个任务栈中可以有多个实例。这种模式下的Activity在创建时它的onCreate、onStart都会被调用。这是一种典型的多实例实现,谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity所在的栈中。
a、当从非Activity的context启动activity时,需要带new_task的flag。
b、当启动一个带有affinity的activity,如果这个activity已经有实例存在该task中,则不会重新创建
c、如果从应用内启动的standard activity的Affinity就是App默认的Affinity,则会每次新建一个实例
2.singleTop
一个singleTop Activity的实例可以无限多,唯一的区别是如果在栈顶已经有一个相同类型的Activity的实例,intent不会再创建一个Activity实例,而是通过onNewIntent()被发送到现有的Activity。
3、singleTask
这是一种单实例模式,只要Activity实例在栈中存在,那么多次启动Activity都不会重新创建实例,和singleTop一样,会回调onNewIntent()。比如创建singleTask模式的ActivityA,系统首先会寻找Activity想要的Task,如果不存在会创建这个Task,然后创建ActivityA的实例并将其放入Task中;若Task已存在,则检查此Task中是否已存在ActivityA实例,如果存在会把ActivityA上的其他Activity实例出栈,知道ActivityA实例到达栈顶,并回调onNewIntent(),否则直接创建新的ActivityA实例并放入Task栈顶。
4、singleInstance
与singleTask相同,只是系统不会将任何其他Activity的实例放到此Task中,该Activity实例始终是Task中的唯一成员。由此Activity启动的任何Activity均在单独的任务中打开,也就是此种模式的Activity只能单独的位于一个任务栈中。
三、应用场景