首先我们说一说Activity为什么需要启动模式,我们都知道,在默认的情况的,当我们多次启动同一个Activity,系统会创建多个实例,一一放入栈中,当我们单击back键,这些Activity会一一回退,任务栈是一种“后进先出” 的栈结构,这个比较好理解,每次点击一下back,就会有一个Activity出栈,当栈中无任何Activity的时候,系统就会回收这个任务栈。知道了Activity的模式启动模式之后,我们就会发现一个问题,多次启动同一个Activity的时候,系统重复创建多个实例,这样不是很傻吗,这样的确有点傻,android在设计的时候不可能不考虑到这个问题,所以它提供了启动模式来修改系统的默认行为,目前有四种启动模式,下面一一介绍:
standard:Activity的默认加载方法,即使某个Activity在Task栈中已经存在,另一个activity通过Intent跳转到该activity,同样会新创建一个实例压入栈中。例如:现在栈的情况为:A B C D,在D这个Activity中通过Intent跳转到D,那么现在的栈情况为: A B C D D 。此时如果栈顶的D通过Intent跳转到B,则栈情况为:A B C D D B。此时如果依次按返回键,D D C B A将会依次弹出栈而显示在界面上。在这种情况下,谁启动了这个Activity,那么这个Activity就运行在启动它的Activity的栈中。
singleTop:如果某个Activity的Launch mode设置成singleTop,那么当该Activity位于栈顶的时候,再通过Intent跳转到本身这个Activity,则将不会创建一个新的实例压入栈中。同时它的onNewIntent方法会被回调,我们可以通过此方法获取请求的信息,需要注意的是,它的onCreate onStart方法将不会执行,因为它并没有发生。例如:现在栈的情况为:A B C D。D的Launch mode设置成了singleTop,那么在D中启动Intent跳转到D,那么将不会新创建一个D的实例压入栈中,此时栈的情况依然为:A B C D。但是如果此时B的模式也是singleTop,D跳转到B,那么则会新建一个B的实例压入栈中,因为此时B不是位于栈顶,此时栈的情况就变成了:A B C D B。
singleTask:如果某个Activity是singleTask模式,那么Task栈中将会只有一个该Activity的实例,和singleTop一样,系统也会调用其onNewIntent。例如:现在栈的情况为:A B C D。B的Launch mode为singleTask,此时D通过Intent跳转到B,则栈的情况变成了:A B。而C和D被弹出销毁了,也就是说位于B之上的实例都被销毁了。
singleInstance:将Activity压入一个新建的任务栈中。例如:Task栈1的情况为:A B C。C通过Intent跳转到D,而D的Launch mode为singleInstance,则将会新建一个Task栈2。此时Task栈1的情况还是为:A B C。Task栈2的情况为:D。此时屏幕界面显示D的内容,如果这时D又通过Intent跳转到D,则Task栈2中也不会新建一个D的实例,所以两个栈的情况也不会变化。而如果D跳转到C,则栈1的情况变成了:A B C C,因为C的Launch mode为standard,此时如果再按返回键,则栈1变成:A B C。也就是说现在界面还显示C的内容,不是D。
那么如何给Activity指定启动模式呢,有两种方法,一种是通过androidMenifest为Activity指定启动模式,如下所示
<activity android:name=".MainActivity2"
android:configChanges="screenLayout"
android:launchMode="singleTask"></activity>
另一种情况是通过Intent设置标志位来为Activity设置启动模式,如下所示
Intent i = new Intent(MainActivity.this,MainActivity2.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
这两种方法都可以为Activity指定启动模式,但还是有区别的,首先,在优先级上,第二种方式的优先级要高于第一种,当两种同时存在时,以第一种为准;其次,上述两种方式在范围限定上有所不同,比如,第一种方式无法为Activity设置 FLAG_ACTIVITY_CLEAR_TOP,而第二种无法为Activity指定 singgleInstance 模式。
下面再介绍一下Activity常用的标志位
FLAG_ACTIVITY_NEW_TASK
这个标志位的作用是为Activity指定“singleTask”模式,其效果和在xml指定该启动模式相同
FLAG_ACTIVITY_SINGLE_TOP
这个标志位的作用是为Activity指定“singleTop”模式,其效果和在xml指定该启动模式相同
FLAG_ACTIVITY_CLEAR_TOP
具有此标记位的Activity,当它启动时,在同一个任务栈中,位于它之上的Activity都要出栈,这个模式一般要和FLAG_ACTIVITY_NEW_TASK配合使用,在这种情况下,被启动的Activity实例如果已经存在,那么系统就会调用它的onNewIntent。如果被启动的Activity采用standard模式,那么它连同它之上的Activity都要出栈,系统会创建新的Activity实例并放入栈顶。singleTask启动模式默认就有此标记位的效果。
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
具有这个标志位的Activity不会出现在历史Activity列表中,当某些情况下,我们不希望用户通过历史列表回到我们的Activity的时候,这个标志比较有用,它等同于在xml中指定Activity的属于为android:excludeFromRecents="true"