Android activity常用的四种启动模式,经常会被问到,下面简单介绍一下
standard:标准模式。这个也是系统默认的启动模式,每次启动一个Activity都会生成一个实例加入到任务栈中,不管任务栈中是否有该实例,谁启动的Activity,该Activity就会加入到启动他的那个Activity的任务栈中。
这里有一点注意:
当我们启动Activity的时候,启动者没有任务栈的时候,会报错,如下:
android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity,Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
比如我们通过收到一条广播后去启动一个Activity的时候就需要注意,广播自身是没有任务栈的,所以通过他的context去启动Activity的时候就需要加上一个flag,如下:
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
通过这个flag启动的Activity的是在一个新的任务栈中,也就后面我们要讲的singleTast启动模式。
singleTop:栈顶复用模式。这种模式下如果新创建的Activity处于栈顶,那么不会重新创建实例,同时它的onNewIntent方法会被回调,通过此方法的参数可以取出数据。需要注意由于Activity并没有创建,所以onCreate、onStart并不会被调用。
举个栗子:
任务栈内有A、B两个Activity了,这个时候在启动一个B,如果B的启动模式是singleTop的那么任务栈中只有A、B,如果B的启动模式是standard的,那么任务栈中是A、B、B了。
- singleTast:栈内复用模式。Activity在栈内存在实例,那么多次启动都不会创建实例,启动它的时候会把它调到栈顶,就是把它之上的Activity都弹出栈,并且和singleTop一样会调用onNewIntent方法。
- singleInstance:单实例模式。该模式应该算是一个特殊的singleTast模式,因为它包含singleTast的特性,并且它要求必须在一个独立的任务栈中,不允许其他Activity加入。
介绍几种特殊的栗子
- a任务栈中有 Activity A 和 Activity B。b任务栈中有 Activity C 和 Activity D(D在栈顶),并且是后台任务栈,启动模式为singleTast的。
- Activity A启动Activity D,则会把整个任务栈切换到前台,C和D会被压到任务栈a中。
- 然后按下返回键,依次出栈的是D->C->B->A
相同的条件下
- Activity A启动Activity C,则会把整个任务栈切换到前台,并且C会先把D弹出栈,C会被压到任务栈a中。
- 然后按下返回键,依次出栈的是C->B->A
如何使用这些启动模式呢?
- 通过在AndroidMenifest中进行设置。如下:
<activity android:name=".MainActivity" android:launchMode="standard" />
- 通过代码进行设置,如下代码:
Intent intent = new Intent(MainActivity.this,ActivityA.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
上面两种方式都可以设置,但是效果不是完全相同,代码设置的优先级要比清单文件中设置优先级高。
其次,两种方式可设置的启动方式不同,方式一无法设置FLAG_ACTIVITY_CLEAR_TOP,第二种无法设置singleInstance模式。