活动启动有以下四种模式:standard、singleTop、singletask、singleInstance
项目完整代码
https://github.com/Phil-tom/Android-The-First-Line-of-Code/tree/main/Chapter2/ActivityTest
1、standard
standard是活动默认的启动模式,系统不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建该活动的新的实例。
每点击一次按钮就会创建一个新的FirstActivity实例,需要按多次Back键才能退出
个人觉得:如果没有在软件中设置返回按钮来返回特定的界面的话,用户体验感会不好
点击BTN1这个按钮,观察日志输出
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstActivity.this, FirstActivity.class);
startActivity(intent);
}
});
每次启动都会创建该活动的一个新的实例。
2、singleTop
在启动活动时发现返回栈的栈顶已经是该活动,则认为可以直接使用它,不会再创建新的活动实例
在Manifest.xml文件的activity标签下添加
android:launchMode="singleTop"
结果是只会出现一条打印信息,在创建完成以后,点击btn1的按钮也不会有反应
注意:当FirstActivity并未处于栈顶位置时,再次启动FirstActivity还是会创建新的实例
修改FirstActivity代码
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
SecondActivity代码
private static final String TAG = "SecondActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate: "+this.toString());
setContentView(R.layout.second_layout);
Button button2 = (Button) findViewById(R.id.button_2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(SecondActivity.this, FirstActivity.class);
startActivity(intent);
}
});
}
结果证明了:当FirstActivity并未处于栈顶位置时,再次启动FirstActivity还是会创建新的实例
3、singleTask
每次启动该活动时系统会在返回栈中检查是否存在该活动的实例。如果发现已经存在,直接使用该实例,并把这个活动之上的所有活动统统出栈。如果没有发现就会创建一个新的实例。
修改Manifest.xml文件的activity标签下添加
android:launchMode="singleTsk"
FirstActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate: "+this.toString());
setContentView(R.layout.second_layout);
Button button2 = (Button) findViewById(R.id.button_2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(SecondActivity.this, FirstActivity.class);
startActivity(intent);
}
});
}
@Override
protected void onRestart() {
super.onRestart();
Log.d(TAG, "onRestart: ");
}
SecondActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate: "+this.toString());
setContentView(R.layout.second_layout);
Button button2 = (Button) findViewById(R.id.button_2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(SecondActivity.this, FirstActivity.class);
startActivity(intent);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ");
}
在SecondActivity中启动FirstActivity时,会发现返回栈中已经存在FirstActivity的实例,并且是在SecondActivity的下面,于是,SecondActivity从返回栈中出栈,而FirstActivity成为返回栈中的栈顶活动,只要按一次Back键就可以退出程序。
4、singleInstance
这种模式的活动会启用一个新的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,都共用的同一个返回栈,解决了共享活动实例的问题。
前三种启动模式做不到,因为每一个应用程序都有自己的返回栈,同一个活动在不同的返回栈中入栈时必然创建了新的实例。
Manifest.xml中
<activity android:name=".SecondActivity"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="com.zzz.activitytest.ACTION_START"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="com.zzz.activitytest.MY_CATEGORY"/>
</intent-filter>
</activity>
FirstActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//打印返回栈的id
Log.d(TAG, "onCreate: Task id is" + getTaskId());
setContentView(R.layout.first_layout);
Button button1 = (Button) findViewById(R.id.button_1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);
}
});
}
SecondActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//打印返回栈的id
Log.d(TAG, "onCreate: Task id is" + getTaskId());
setContentView(R.layout.second_layout);
Button button2 = (Button) findViewById(R.id.button_2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(SecondActivity.this, ThirdActivity.class);
startActivity(intent);
}
});
}
ThirdActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//打印返回栈的id
Log.d(TAG, "onCreate: Task id is "+getTaskId());
setContentView(R.layout.third_layout);
}
SecondActivity的返回栈id不同于FirstActivity和ThirdActivity,说明SecondActivity确实放在一个单独的返回栈里,这个栈中只有SecondActivity一个活动。
当前活动假设是ThirdActivity,按下Back键,回到FirstActivity(这两个活动在同一个返回栈中),再按Back键,这是栈已经空了,于是就显示另一个返回栈的栈顶活动,所以回到SecondActivity,再按Back键,所有栈都空了,退出程序。
个人觉得这个图片很形象,singleInstance模式示意图