简介
在配置Activity时,可以指定android:launchMode
属性,该属性用于配置该Activity
的加载模式,支持如下四种模式
- standard 标准模式,这是默认的加载模式
- singleTop Task顶单例模式
- singleTask Task内单例模式
- singleInstance 全局单例模式
Android采用Task来管理多个Activity,当启动一个应用时,系统为之创建一个Task,然后启动入口Activity。Android并没有为Task提供API,所以我们不能直接访问Task,只能调用getTaskID()
来获取Activity所在Task的ID。我们可以把Task理解为栈,先启动的Acitivity放在栈底,后启动的Activity放在栈顶。
Activity的加载模式,就是负责管理实例化、加载Activity的方式,并控制Activity与Task之间的加载关系。
standard 模式
每次通过这种模式启动目标Activity时,系统会为目标Activity创建新的实例,并将该Activity加入当前Task栈中。这种模式不会启动新的Task,新的Acitivty将被加入到原有Task中。
singleTop 模式
将要被启动的Avtivity没有在Task栈顶时,与standard模式无异。当要启动的Activity已经位于Task栈顶时,系统不会重新创建目标Activity实例,而是复用已有的Activity实例。
singleTask 模式
当采用这种模式时,要加载的Activity在同一Task内只会存在唯一实例。系统采用singleTask模式启动目标Activity时,会有如下三种可能性
- 将要启动的Activity在Task栈中不存在,则系统会创建目标Activity的实例,并将它加入Task栈顶。
- 将要启动的Activity已在Task栈顶,此时与singleTop模式行为相同。
- 将要启动的目标Activity已存在,但不在Task栈顶,系统将会把位于该Activity上面的所有Activity移出Task栈,从而使目标Activity转到栈顶。
singleInstance 模式
在这种模式下,系统保证无论从哪个Task栈中启动目标Activity,只会创建一个目标Activity实例,并会使用一个全新的栈来装在该Activity实例。有如下两种情况
- 要启动的目标Activity不存在时,系统会创建一个全新的Task,再创建目标Activity的实例,并将它加入新创建的Task的栈顶。
- 要启动的目标Activity已存在时,无论它在哪个应用程序中,无论它位于哪个Task栈中,系统会把该Activity所在的Task转到前台,从而使该Activity显示出来。
采用singleInstance模式启动的Activity,它所在的Task只包含该Acitivty,并且该Activity总位于栈顶(显而易见)。
简单的例子
举个例子说明一下singleInstance模式。
程序A有三个界面,加载关系为A1->A2->A3。其中A2的启动模式为singleInstance
。下面的A2在manifest
中的配置。
<activity
android:name=".SingleInstanceActivity"
android:exported="true"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="test.launch_mode" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
需要说明的是设置android:exported="true"
是为了使外部应用可以启动A2。因此要同时添加一个intent-filter
,设置action
,并且一定要加上category android:name="android.intent.category.DEFAULT"
这一条,否则在其他程序启动A2时会报错。
程序B有一个界面B1,但B1可以启动A2,代码为
Intent intent = new Intent("test.launch_mode");
startActivity(intent);
打开A程序,依次启动A1,A2,A3,得到的Task栈如图。

可以看到A2自己位于一个全新的栈中,通过A2启动的A3则会放到原来的栈中。
这时按下HOME键,把A程序切换至后台,启动B程序,并通过B程序启动A2,A2再启动A3,得到的Task栈如图

红色的箭头是B程序Activity的切换或创建的顺序。
可以看到B1启动A2时,由于系统中存在A2,所以仅仅是将A2所在Task切换至前台,显示A2。
A2启动A3时,由于A3的启动方式为standard
,所以会在A3所在程序(A程序)的栈中再实例化一个A3。
当按BACK依次关闭Activity时,关闭顺序为
A3(上)->A3(下)->A1->A2->B1
不同启动模式的使用场景
使用场景的内容摘自网上,感觉说得还不错。更多的场景,还是在开发过程中慢慢体会吧。
-
singleTop适合接收通知启动的内容显示页面
例如,某个新闻客户端的新闻内容页面,如果收到10个新闻推送,每次都打开一个新闻内容页面是很烦人的。 -
singleTask适合作为程序入口点
例如,浏览器的主界面。不管从多少个应用启动浏览器,只会启动主界面一次,其余情况都会走onNewIntent,并且会清空主界面上面的其他页面。 -
singleInstance适合需要与程序分离开的页面
例如,闹铃提醒,将闹铃提醒与闹铃设置分离。singleInstance不要用于中间页面,如果用于中间页面,跳转会有问题。
网友评论