在默认情况下,启动Activity时,系统会默认创建实例,并把它放入到栈中,以方便我们回退到上一个。而栈是一种先进后出的栈结构。如果经常多次创建或者启动同一个Activity,我们就会发现栈里会出现同个Activity的多个实例,这样就会重复创建多个实例,会不会很浪费资源呢?因此Android提供了启动模式来修改系统的默认行为。目前有四种启动模式:standard,singleTop,singleTask和singleInstance。
singleTask---- 栈内复用模式。这是一种单实例模式。在这种模式下,只要Activity在一个栈中存在,那么多次启动都不会重新创建。和singleTop一样,会回调onNewIntent方法。具体一点,当一个具有该模式的Activity请求启动后,系统首先会寻找是否存在A想要的任务栈,即是否存在启动Acitivity的任务栈,如果不存在重新创建新的任务栈和新的activity实例。如果存在,这时去检查栈中是否已经存在该实例,如果不存在则创建,如果存在那么系统会把实例调到栈顶并调用它的onNewIntent,由于singleTask默认具有cleanTop效果,当吧实例调到栈顶时会导致该实例上面所有Activity出栈。
singleInstance---- 单实例模式。这时一种加强的singleTask模式,它除了具有singleTask的所有特性外,还加强了一点,那就是具有此模式的Activity只能单独的位于一个任务栈中
有两种启动方法:
一种是在AndroidMenifest文件中为Activity指定模式:
如:
<Activity android:name="com.zb,test" android:launchermode = "singtask"/>另外一种是通过代码设置,即在Intent中设置标志位来为Activity指定模式。
如:
Intent inten = new Intent(); intent,setClass(MainActivity.this,SecondActivity.class); intent.addFlag(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent);这两种方式都可以指定启动模式,但是还是有一定区别的。首先第二种的优先级高于第一种,其次,这两种方式在限定范围上有所不同,比如,第一种无法为Activity直接添加 ACTIVITY_FLAG_CLEAN_TOP标识,而第二种方式无法为Activity指定singleInstance。
1.FLAG_ACTIVITY_CLEAR_TOP:例如现在的栈情况为:A B C D 。D此时通过intent跳转到B,如果这个intent添加FLAG_ACTIVITY_CLEAR_TOP标记,则栈情况变为:A B。如果没有添加这个标记,则栈情况将会变成:A B C D B。也就是说,如果添加了FLAG_ACTIVITY_CLEAR_TOP标记,并且目标Activity在栈中已经存在,则将会把位于该目标activity之上的activity从栈中弹出销毁。这跟上面把B的Launch mode设置成singleTask类似。
2.FLAG_ACTIVITY_NEW_TASK:例如现在栈1的情况是:A B C。C通过intent跳转到D,并且这个intent添加了FLAG_ACTIVITY_NEW_TASK标记,如果D这个Activity在Manifest.xml中的声明中添加了Task affinity,并且和栈1的affinity不同,系统首先会查找有没有和D的Task affinity相同的task栈存在,如果有存在,将D压入那个栈,如果不存在则会新建一个D的affinity的栈将其压入。如果D的Task affinity默认没有设置,或者和栈1的affinity相同,则会把其压入栈1,变成:A B C D,这样就和不加FLAG_ACTIVITY_NEW_TASK标记效果是一样的了。 注意如果试图从非activity的非正常途径启动一个activity,比如从一个service中启动一个activity,则intent比如要添加FLAG_ACTIVITY_NEW_TASK标记。 3.FLAG_ACTIVITY_NO_HISTORY:例如现在栈情况为:A B C。C通过intent跳转到D,这个intent添加FLAG_ACTIVITY_NO_HISTORY标志,则此时界面显示D的内容,但是它并不会压入栈中。如果按返回键,返回到C,栈的情况还是:A B C。如果此时D中又跳转到E,栈的情况变为:A B C E,此时按返回键会回到C,因为D根本就没有被压入栈中。
4.FLAG_ACTIVITY_SINGLE_TOP:和上面Activity的Launch mode的singleTop类似。如果某个intent添加了这个标志,并且这个intent的目标activity就是栈顶的activity,那么将不会新建一个实例压入栈中。
5.FLAG_ACTIVITY_BROUGHT_TO_FRONT:比如说我现在有A,在A中启动B,此时在A中Intent中加上这个标记。此时B就是以FLAG_ACTIVITY_BROUGHT_TO_FRONT方式启动,此时在B中再启动C,D(正常启动C,D),如果这个时候在D中再启动B,这个时候最后的栈的情况是 A,C,D,B。如果在A,B,C,D正常启动的话,不管B有没有用FLAG_ACTIVITY_BROUGHT_TO_FRONT启动,此时在D中启动B的话,还是会变成A,C,D,B的。
6.FLAG_ACTIVITY_NO_HISTORY:这个FLAG启动的Activity,一旦退出,它不会存在于栈中,比方说!原来是A,B,C这个时候再C中以这个FLAG启动D的,D再启动E,这个时候栈中情况为A,B,C,E。
7.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS :如果设置,新的Activity不会在最近启动的Activity的列表中保存。
8.FLAG_ACTIVITY_MULTIPLE_TASK :与FLAG_ACTIVITY_NEW_TASK结合使用, 首先在Intent中设置FLAG_ACTIVITY_NEW_TASK, 打开Activity,则启动一个新Task, 接着在Intent中设置FLAG_ACTIVITY_MULTIPLE_TASK, 再次打开同一个Activity,则还会新启动一个Task.。