引言
Activity有四种启动模式standard(默认),singleTop,singleTask,singleInstance,相信大家都知道,但是它们之间到底有什么区别可能还是有些人说不太清楚,本文将就这四种启动模式的区别做简单的介绍,然后通过实验验证咱们的结论。
四种启动模式介绍
一、standard,
standard是Activity默认的启动模式,如果在AndroidManifest.xml中配置Activity时不指定launchMode属性,Activity会默认使用standard模式。使用standard模式,每次启动Activity时系统都会创建新的Activity实例并加入到当前Activity栈中,Activity栈中可以包含多个这种Activity的实例。
二、singleTop
singleTop与standard非常类似,唯一的区别是要启动的singleTop Activity在当前Activity栈中已经存在,并且处于栈顶时,系统不会再去创建该Activity的实例,而是调用该栈顶Activity的onNewIntent()方法。
三、singleTask
当Activity的启动模式为singleTask时,意味着Activity栈中只会存在一个该Activity的实例,在启动singleTask Activity时,系统会检测当前Activity栈中是否有该Activity的实例,如果存在,系统会关闭该Activity之上的其他Activity,使该singleTask Activity成为栈顶Activity,并且调用该singleTask Activity的onNewIntent()方法。如果不存在,系统会创建新的Activity实例加入当前Activity栈。
四、singleInstance
声明为singleInstance模式的Activity会单独占用一个Activity栈,该Activity栈中不能有其他Activity。
实验验证
我们定义四个Activity,其名称和启动模式对应如下:
- ActivityStandard(standard)
- ActivitySingleTop(singleTop)
- ActivitySingleTask(singleTask)
- ActivitySingleInstance(singleInstance)
它们共用一套布局文件,布局代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<Button
android:id="@+id/btnStartStandard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="btnStartStandard" />
<Button
android:id="@+id/btnStartSingleTop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="btnStartSingleTop" />
<Button
android:id="@+id/btnStartSingleTask"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="btnStartSingleTask" />
<Button
android:id="@+id/btnStartSingleInstance"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="btnStartSingleInstance" />
</LinearLayout>
各Activity的Java代码相同,代码如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btnStartStandard).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(), ActivityStandard.class));
}
});
findViewById(R.id.btnStartSingleTop).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(), ActivitySingleTop.class));
}
});
findViewById(R.id.btnStartSingleTask).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(), ActivitySingleTask.class));
}
});
findViewById(R.id.btnStartSingleInstance).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(), ActivitySingleInstance.class));
}
});
}
情况一:A为standard模式,A启动A,再启动A,此时当前Activity栈中为A-A-A;
情况二:A为standard模式,B为singleTop模式,A启动B,再启动B,此时当前Activity栈中为A-B,第二次启动B时不会创建新的B的实例,只会调用B的onNewIntent()方法;
情况三:A为standard模式,B为singleTask模式,A启动B,再启动A,此时当前Activity栈中为A-B-A,再启动B,此时当前Activity栈中为A-B;
情况四:A为standard模式,B为singleInstance模式,A启动B,当前栈为A,新开辟的栈中为B,在启动A,当前栈为A-A,新开辟栈为B,再启动B,当前栈为A-A,新开辟栈为B
使用Intent Flag设置启动模式
除了在AndroidManifest.xml设置launchMode,还可以在代码中通过设置Intent Flag来设置启动模式,主要有以下三种比较常用的Flag:
- FLAG_ACTIVITY_NEW_TASK
- FLAG_ACTIVITY_CLEAR_TOP
- FLAG_ACTIVITY_SINGLE_TOP