Activity的4种启动模式
每个应用程序都是由一个或者多个Activity组成,一次Android内部使用通过回退栈来管理Activity实例。栈是一种后进先出的集合,对于Android来说,当前显示的Activity就在栈顶,当用户点击后退键或者点击应用上的返回按钮,系统就会将栈顶的Activity出栈,此时原来栈顶下的Activity就会变成栈顶显示到设备上。
Activity的启动模式有4个,分别为standard、singleTop、singleTask、singleInstance。
用户可以通过AndroidManifest.xml注册Activity时 设置它的启动模式,例如:
<activity
android:name = ".MyActvity"
android:launchMode = "singleTask"
android:label="@string/app_name">
</activity>
1. standard(标准启动模式)
这是Activity的标准启动模式,也是Activity的默认启动模式。在这种模式下启动的Activity可以被多次实例化,即在同一个任务栈中可以存在多个Activity实例,每个实例都会处理一个Intent对象。如果ActivityA的启动模式为standard,并且已经有一个ActivityA被启动,在该ActivityA中调用startActivity时会启动一个新的ActivityA实例。栈的变化如图1所示。
图1:栈中有多个ActivityA实例
如果ActivityA是一个非常耗资源的类,那么将会使它所依附的应用消耗更多的系统资源。
2. singleTop(栈顶复用模式)
如果一个以singleTop模式启动的Activity的实例已经存在于任务栈的栈顶,那么启动这个Activity时,不会创建新的实例,而是重用位于栈顶的那个实例,并且会调用该实例的onNewIntent()函数将Intent对象传递到这个实例中。例如,ActivityA的启动模式为singleTop,并且ActivityA的一个实例已经存在于栈顶中。那么在调用startActivity启动另一个ActivityA时,不会再次创建ActivityA的实例,而是重用原来的实例,并且调用原来实例的onNewIntent()函数。此时任务栈中还是这一个ActivityA的实例。栈内变化如图2所示。
图2:栈顶的ActivityA被重用
如果singleTop模式启动的Activity的一个实例已经存在于任务栈中,但是不在栈顶,那么它的行为和standard模式相同也会创建一个新的实例。栈内变化如图3所示。
图3:不在栈顶,重新创建一个ActivityA
3. singleTask(栈内复用模式)
singleTask模式是常用的启动模式,如果一个Activity设置了改启动模式,那么在一个任务栈中只能有一个该Activity的实例(即任务栈中的实例各不相同)。如果任务栈中还没有该Activity,会新创建一个实例并放在栈顶。但是,如果已经存在Activity,系统会销毁处在该Activity上的所有Activity,最终让该Activity实例处于栈顶,同时回调改Activity的onNewIntent()函数。栈内变化如图4所示。
图4:处在ActivityA上的Activity被销毁
4. singleInstance(singleTask的加强版)
设置了singleInstance模式的Activity会在一个独立的任务中开启,并且这个新的任务中有且仅有这一个实例,也就是说呗该实例启动的其他Activity会自动运行于另一个任务中。当再次启动该Activity实例时,会重用已存在的任务和实例。并且会调用该实例的onNewIntent()函数,将Intent实例传递到该实例中。
和singleTask不同的是,同一时刻在系统中只会存在一个这样的Activity实例,而singleTask模式的Activity是可以有多个实例的,只要这些Activity在不同的任务栈中即可,例如,应用 A启动了一个模式为singleTask的ActivityA,应用B有又通过Intent想要启动一个ActivityA,此时由于应用A和应用B都有自己的任务栈,因此,在这两个任务栈中分别都有一个ActivityA实例。而singleInstance能够保证Activity在系统只有一个实例,不管多少应用要启动该Activity,这个Activity有且只有一个,如图5所示。
图5:singleInstance的Activity独占一个任务栈