想要了解什么是Activity的启动模式之前 先要知道 什么是 返回栈
Android是使用任务(Task)来管理Acitivity的,一个任务就是一组存放在栈里的Activity的集合,这个栈也被称作返回栈(Back
Stack)。栈是一种后进先出的数据结构,在默认情况下,每当我们启动了一个新的Activity,它都会在返回栈中入栈,并处于栈顶的位置。而每当我们按下Back键或调用finish()方法去销毁一个Activity时,处于栈顶的Activity会出栈,这时前一个入栈的活动就会重新处于栈顶的位置。系统总是会显示处于栈顶的Activity给用户。
Activity的启动模式一共分为 4 种 分别是 Standard , SingleTop , SingleTask , SingleInstance:
1,standard
standard是活动默认的启动模式,在不进行显式指定的情况下,所有活动都会自动使用这种启动模式。在standard模式下,每当启动一个新的Activity,它就会在返回栈中入栈,并处于栈顶的位置。对于使用standard模式的Activity,系统不会在乎这个Activity是否已经在返回栈中存在,每次启动Activity都会创建该Activity的一个新的实例。
比如说 在一个 FirstActivity当中 调用两次 Intent intent = new Intent(FirstActivity.this, FirstActivity.class); startActivity(intent);
这样在standard模式中 现在在返回栈 中存在三个FirstActivity 这时你按三次 Back 键才能退出应用。
2,SingleTop
可能在有些情况下,你会觉得standard模式不太合理。FirstActivity明明已经在栈顶了,为什么再次启动的时候还要创建一个新的FirstActivity实例呢?别着急,这只是系统默认的一种启动模式而已,你完全可以根据自己的需要进行修改,比如说使用singleTop模式。当活动的启动模式指定为singleTop,在启动活动时如果发现返回栈的栈顶已经是FirstActivity,则认为可以直接使用它,不会再创建新的活动实例。
修改AndroidManifest.xml中FirstActivity的启动模式,如下所示:
<activity
android:name=".FirstActivity"
android:launchMode="singleTop"
android:label="This is FirstActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
之后不管调用多少次 Intent intent = new Intent(FirstActivity.this, FirstActivity.class); startActivity(intent);都不会从新创建FirstActivity对象 这时按一次Back键 就能退出程序。
3,SingleTask
使用singleTop模式可以很好地解决重复创建栈顶活动的问题,但是正如你在上一节所看到的,如果该活动并没有处于栈顶的位置,还是可能会创建多个活动实例的。
那么有没有什么办法可以让某个活动在整个应用程序的上下文中只存在一个实例呢?这就要借助singleTask模式来实现了。
当活动的启动模式指定为singleTask,每次启动该活动时系统首先会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这个活动之上的所有活动统统出栈,如果没有发现就会创建一个新的活动实例。
<activity
android:name=".FirstActivity"
android:launchMode="SingleTask"
android:label="This is FirstActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
在A当中启动B 然后在B中再次启动 A 这时 按一次Back 键就能退出程序。
4,SingleInstance
不同于以上三种启动模式,指定为singleInstance模式的活动会启用一个新的返回栈来管理这个活动(其实如果singleTask模式指定了不同的taskAffinity,也会启动一个新的返回栈)。那么这样做有什么意义呢?想象以下场景,假设我们的程序中有一个活动是允许其他程序调用的,如果我们想实现其他程序和我们的程序可以共享这个活动的实例,应该如何实现呢?使用前面三种启动模式肯定是做不到的,因为每个应用程序都会有自己的返回栈,同一个活动在不同的返回栈中入栈时必然是创建了新的实例。而使用singleInstance模式就可以解决这个问题,在这种模式下会有一个单独的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,都共用的同一个返回栈,也就解决了共享活动实例的问题。
<activity
android:name=".SecondActivity"
android:launchMode="singleInstance" >
<intent-filter>
<action android:name="com.example.activitytest.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.example.activitytest.MY_CATEGORY" />
</intent-filter>
</activity>
比如 有三个Activity A B C (B被标识为SingleInstance)
A 中 启动 B ,在B中 启动 C
在C 中按返回键 这时会返回到A
在A 中在按返回键 这时会回到B
在B 中按返回键 这时才退出程序。