standard:标准模式,即默认启动模式;
singleTop:顶单例模式,即要求实例处于栈顶;
singleTask:内单例模式,即要求栈中只有一个实例;
singleInstance:全局单例模式;
接下来将会对以上4种加载模式进行讲解。
每次通过这种模式启动目标Activity时,android总会为目标Activity创建一个新的实例,并将该实例添加到当前的任务栈中,这种模式不会启动新的任务栈,新创建的Activity实例将被添加到原有的任务栈中。如:
public class StandardActivity extends AppCompatActivity {
private TextView tv_content;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_standard);
tv_content = (TextView) findViewById(R.id.tv_content);
tv_content.setText("当前Activity为:"+"\n"
+this.toString()
+"\n"+" TaskId为:"+this.getTaskId());
}
public void skip2StandardActivity(View view){
Intent intent = new Intent(StandardActivity.this,StandardActivity.class);
startActivity(intent);
}
}
运行程序,可以发现每次点击StandardActivity都会创建一个新的StandardActivity实例,在控制台中输入:
adb shell dumpsys activity
然后回车可以看到
Activity
的栈情况
需要注意的是,Standard加载模式无须配置目标Activity的launchMode属性,目标Activity会默认采用standard加载模式。
singleTop模式与standard模式基本相似,唯一不同的是,当将要被启动的目标Activity已经处于任务栈栈顶时,系统不会重新创建目标Activity的实例,而是直接复用已有的Activity,当然,如果将要被启动的目标Activity没有位于任务栈栈顶的话,此时系统会重新目标Activity,并将创建的新的Activity实例添加到任务栈中(此时与standard加载模式相同)。如:
public class StandardActivity extends AppCompatActivity {
private TextView tv_content;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_standard);
tv_content = (TextView) findViewById(R.id.tv_content);
tv_content.setText("当前Activity为:"+"\n"
+this.toString()
+"\n"+" TaskId为:"+this.getTaskId());
}
public void skip2StandardActivity(View view){
Intent intent = new Intent(StandardActivity.this,StandardActivity.class);
startActivity(intent);
}
public void skip2SingleTopActivity(View view){
Intent intent = new Intent(StandardActivity.this,SingleTopActivity.class);
startActivity(intent);
}
}
目标SingleTopActivity 的主要代码如下所示:
public class SingleTopActivity extends AppCompatActivity {
private TextView tv_content;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_standard);
tv_content = (TextView) findViewById(R.id.tv_content);
tv_content.setText("当前Activity为:"+"\n"
+this.toString()
+"\n"+" TaskId为:"+this.getTaskId());
}
public void skip2StandardActivity(View view){
Intent intent = new Intent(SingleTopActivity.this,StandardActivity.class);
startActivity(intent);
}
public void skip2SingleTopActivity(View view){
Intent intent = new Intent(SingleTopActivity.this,SingleTopActivity.class);
startActivity(intent);
}
}
另外,需要在
AndroidManifest
清单文件中为目标
SingleTopActivity
配置
launchMode
属性,并将其指定为
singleTop
,如下所示:
此时,运行程序可以发现,当在
StandardActivity
中点击
SingleTopActivity
按钮时会创建一个
SingleTopActivity
的实例,当在
SingleTopActivity
中点击
SingleTopActivity
按钮时,由于
SingleTopActivity
已经在任务栈的栈顶,因此不会再创建新的实例,当然,如果在
SingleTopActivity
中点击
StandardActivity
按钮回到
StandardActivity
界面时,此时再点击
SingleTopActivity
按钮,会发现,又创建了一个新的
SingleTopActivity
的实例。同样的,在控制台输入:
adb shell dumpsys activity
命令可以查看
Activity
的任务栈情况如下所示:
采用singleTask加载模式的Activity在同一个任务栈内只有一个实例,当系统采用singleTask模式启动目标Activity时,可分为如下几种情况:
1)如果将要启动的目标Activity不存在,系统将会创建目标Activity的实例,并将它添加到任务栈的栈顶中;
2)如果将要启动的目标Activity已经位于任务栈的栈顶,此时与singleTop模式相同,系统不会重新创建新的目标Activity的实例,而是直接复用已有的Activity实例;
3)如果将要启动的目标Activity已经存在,但没有位于任务栈的栈顶,那么此时系统将会把位于该Activity上面的所有Activity移出任务栈,从而使得目标Activity处于任务栈的栈顶。如
public class StandardActivity extends AppCompatActivity {
private TextView tv_content;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_standard);
tv_content = (TextView) findViewById(R.id.tv_content);
tv_content.setText("当前Activity为:"+"\n"
+this.toString()
+"\n"+" TaskId为:"+this.getTaskId());
}
public void skip2StandardActivity(View view){
Intent intent = new Intent(StandardActivity.this,StandardActivity.class);
startActivity(intent);
}
public void skip2SingleTaskActivity(View view){
Intent intent = new Intent(StandardActivity.this,SingleTaskActivity.class);
startActivity(intent);
}
}
SingleTaskActivity
的代码如下所示:
public class SingleTaskActivity extends AppCompatActivity {
private TextView tv_content;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_standard);
tv_content = (TextView) findViewById(R.id.tv_content);
tv_content.setText("当前Activity为:"+"\n"
+this.toString()
+"\n"+" TaskId为:"+this.getTaskId());
}
public void skip2StandardActivity(View view){
Intent intent = new Intent(SingleTaskActivity.this,StandardActivity.class);
startActivity(intent);
}
public void skip2SingleTaskActivity(View view){
Intent intent = new Intent(SingleTaskActivity.this,SingleTaskActivity.class);
startActivity(intent);
}
}
当然,跟
singleTop
模式一相,同样需要在
AndroidManifest
清单文件中跟
SingleTaskActivity
添加
launchMode
属性并将其指定为
singleTask
,如下所示:
程序运行后,在
StandardActivSity
中点击
SingleTaskActivity
按钮跳转到
SingleTaskActivity
时会创建一个
SingleTaskActivity
的实例,此时点击
StandardActivity
按钮跳转到
StandardActivity
中,在多次点击
StandardActivity
后,再点击
SingleTaskActivity
按钮会发现,此时并没有创建新的
SingleTaskActivity
的实例,并且原先位于
SingleTaskActivity
实例上面的所有
StandardActivity
的实例都消失了。
singleInstance这种加载模式可以保证系统无论从哪个任务栈中启动目标Activity,都只会创建一个目标Activity的实例,并会使用一个全新的任务栈来装载该Activity的实例。
当以singleInstance模式启动目标Activity时,可分为如下两种情况:
1)如果将要启动的目标Activity不存在,系统会先创建一个全新的任务栈,再创建目标Activity的实例,并将它加入到新的任务栈的栈顶;
2)如果将要启动的目标Activity已经存在,无论它位于哪个任务栈中,系统都将会把该Activity所在的任务栈转到最前面,从而使该Activity显示出来。
需要注意的是采用singleInstance模式加载的Activity总是位于任务栈的栈顶,并且加载的Activity所在的任务栈中只包含该Activity。代码如下所示:
public class StandardActivity extends AppCompatActivity {
private TextView tv_content;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_standard);
tv_content = (TextView) findViewById(R.id.tv_content);
tv_content.setText("当前Activity为:"+"\n"
+this.toString()
+"\n"+" TaskId为:"+this.getTaskId());
}
public void skip2StandardActivity(View view){
Intent intent = new Intent(StandardActivity.this,StandardActivity.class);
startActivity(intent);
}
public void skip2SingleInstanceActivity(View view){
Intent intent = new Intent(StandardActivity.this,SingleInstanceActivity.class);
startActivity(intent);
}
}
SingleInstanceActivity的代码如下所示:
public class SingleInstanceActivity extends AppCompatActivity {
private TextView tv_content;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_standard);
tv_content = (TextView) findViewById(R.id.tv_content);
tv_content.setText("当前Activity为:"+"\n"
+this.toString()
+"\n"+" TaskId为:"+this.getTaskId());
}
public void skip2StandardActivity(View view){
Intent intent = new Intent(SingleInstanceActivity.this,StandardActivity.class);
startActivity(intent);
}
public void skip2SingleInstanceActivity(View view){
Intent intent = new Intent(SingleInstanceActivity.this,SingleInstanceActivity.class);
startActivity(intent);
}
}
在
AndroidManifest
清单文件中给
SingleInstanceActivity
添加
launchMode
属性并将其指定为
singleInstance
,代码如下所示:
运行程序可以看出,当在
StandardActivity
中点击
SingleInstanceActivity
按钮时,如果
SingleInstanceActivity
实例不存在,则会先创建一个
SingleInstaceActivity
的实例,在
SingleInstaceActivity
中点击
StandardActivity
按钮回到
StandardActivity
后,连续点击几次
StandardActivity
按钮进行跳转后再点击
SingleInstanceActivity
按钮会发现
SingleInstanceActivity
并没有再次创建新的实例。同样的,在控制台通过:
adb shell dumpsys activity
命令可以查看
Task
栈的情况,从结果中可以发现点击
SingleInstanceActivity
按钮时新创建了一个任务栈并将新创建的
SingleInstanceActivity
的实例添加到了该任务栈中。
此时,关于Activity的启动模式就算是已经讲解完了。
源码