众所周知,android给我们提供了standard、singleTop、singleTask、singleInstance 4种Activity的启动模式,其中:
standard:标准模式,即默认启动模式;
singleTop:顶单例模式,即要求实例处于栈顶;
singleTask:内单例模式,即要求栈中只有一个实例;
singleInstance:全局单例模式;
接下来将会对以上4种加载模式进行讲解。
1、standard模式
每次通过这种模式启动目标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加载模式。
2、singleTop模式
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,如下所示:
<activity android:name=".SingleTopActivity" android:launchMode="singleTop"/>此时,运行程序可以发现,当在StandardActivity中点击SingleTopActivity按钮时会创建一个SingleTopActivity的实例,当在SingleTopActivity中点击SingleTopActivity按钮时,由于SingleTopActivity已经在任务栈的栈顶,因此不会再创建新的实例,当然,如果在SingleTopActivity中点击StandardActivity按钮回到StandardActivity界面时,此时再点击SingleTopActivity按钮,会发现,又创建了一个新的SingleTopActivity的实例。同样的,在控制台输入:adb shell dumpsys activity命令可以查看Activity的任务栈情况如下所示:
3、singleTask模式
采用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,如下所示:
<activity android:name=".SingleTaskActivity" android:launchMode="singleTask"/>程序运行后,在StandardActivSity中点击SingleTaskActivity按钮跳转到SingleTaskActivity时会创建一个SingleTaskActivity的实例,此时点击StandardActivity按钮跳转到StandardActivity中,在多次点击StandardActivity后,再点击SingleTaskActivity按钮会发现,此时并没有创建新的SingleTaskActivity的实例,并且原先位于SingleTaskActivity实例上面的所有StandardActivity的实例都消失了。
4、singleInstance模式
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的代码如下所示:
<span style="font-size:12px;">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); } }</span><span style="font-size:14px;"> </span>在AndroidManifest清单文件中给SingleInstanceActivity添加launchMode属性并将其指定为singleInstance,代码如下所示:
<activity android:name=".SingleInstanceActivity" android:launchMode="singleInstance"/>运行程序可以看出,当在StandardActivity中点击SingleInstanceActivity按钮时,如果SingleInstanceActivity实例不存在,则会先创建一个SingleInstaceActivity的实例,在SingleInstaceActivity中点击StandardActivity按钮回到StandardActivity后,连续点击几次StandardActivity按钮进行跳转后再点击SingleInstanceActivity按钮会发现SingleInstanceActivity并没有再次创建新的实例。同样的,在控制台通过:adb shell dumpsys activity命令可以查看Task栈的情况,从结果中可以发现点击SingleInstanceActivity按钮时新创建了一个任务栈并将新创建的SingleInstanceActivity的实例添加到了该任务栈中。
此时,关于Activity的启动模式就算是已经讲解完了。