活动的启动模式总共有四种,分别是standard、singleTop、singleTask和singleInstance。
一、standard
standard是活动默认的启动模式,每启动一个新的活动,它就会在返回栈中入栈,并处于栈顶的位置。
系统不管这个活动是否已经在返回栈中存在,每次启动都会创建该活动的一个新的实例。standard的原理示意图:
二、singleTop
当活动的启动模式指定为singleTop,在启动活动是如果发现返回栈的栈顶已经是该活动,则认为可以直接使用它,不会再创建新的活动实例。
接下来修改FirstActivity的AndroidManifest.xml文件
<activity
android:name="com.gomez.menutest.FirstActivity"
android:launchMode="singleTop"
android:label="@string/app_name" >
指定launchMode为singleTop,然后修改FirstActivity中的onCreate()方法的代码
@Override
public void onClick(View v) {
String data = "Hello secondActivity";
Intent intent = new Intent(FirstActivity.this, FirstActivity.class);
startActivity(intent);
}
这时你会发现不管你点击多少次,,Logcat中只会打印一次,而且只需按一次back键就可以退出程序。
这说明活动只被创建一次,只要活动已经处于栈顶,每当FirstActivity再启动都会直接使用站定的活动,因此FirstActivity也只有一个实例。
不过当活动并未处于栈顶时,再启动活动,还是会被创建的。
singleTop模式的原理图:
三、singleTask
当活动的启动模式指定为singleTask,每次启动该活动是系统首先会在返回栈中检查是否存在该活动的实例,
如果发现已经存在则直接使用该实例,并把在这个活动之上的的所有活动统统出栈,如果没有发现就会创建一个新的活动实例。
修改FirstActivity的AndroidManifest.xml文件:
<activity
android:name="com.gomez.menutest.FirstActivity"
android:launchMode="singleTask"
android:label="@string/app_name" >
然后重写
FirstActivity的onRestart()方法
@Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Log.d("FirstActivity", "onRestart");
}
再重写Second
Activity的onDestroy()和点击事件方法
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.d("SecondActivity", "onDestroy");
}
public void onClick(View v) {
Intent intent = new Intent(SecondActivity.this, FirstActivity.class);
startActivity(intent);
查看LogCat日志
当SecondActivity启动FirstActivity时,会发现返回栈中已经存在一个FirstActivity实例,于是SecondActivity在返回栈中出栈,
而FirstActivity重新成为栈顶活动,因此FirstActivity的onRestart()和SecondActivity的onDestroy()方法得到执行。
现在返回栈中只剩下FirstActivity实例,按一下back键就会退出程序。
四、singleInstance
singleInstance是四种启动模式中最为特殊和复杂的,指定为singleInstance模式的活动会启动一个新的返回栈来管理这个活动,
如果我们想实现不同的应用程序共享该活动,就必须把活动指定为singleInstance模式启动,
因为每个应用程序都会有自己的返回栈,同一活动在不同的返回栈中必然会重新创建实例。
而singleInstance模式下的活动会有一个单独的返回栈来管理,不管哪个应用程序来访问这个活动,都共用同一个返回栈。
接下来我们来实践一下。修改SecondActivity的启动模式:
<activity
android:name="com.gomez.menutest.SecondActivity"
android:launchMode="singleInstance">
然后修改
FirstActivity的onCreate()方法的代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("FirstActivity", "Task id is" + getTaskId());//打印了当前返回栈的id
Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String data = "Hello secondActivity";
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);
}
}
}
然后修改SecondActivity的onCreate()方法的代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Log.d("SecondActivity", "Task id is " + getTaskId());
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(SecondActivity.this, ThirdActivity.class);
startActivity(intent);
}
}
}
同样在打印返回当前的id,然后启动ThirdActivity活动,最后修改ThirdActivity的onCreate()代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.d("ThirdActivity", "Task id is " + getTaskId());
setContentView(R.layout.activity_main);
}
运行程序,查看LogCat日志:
可以看出,SecondActivity的Task id 不同于FirstActivity和ThirdActivity,说明SecondActivity是存放在一个单独的返回栈里的,
我们按下Back键会发现ThirdActivity返回到FirstActivity,这是因为FirstActivity和ThirdActivity在同一个返回栈中,
再按下Back键当前的返回栈已空,才会返回到SecondActivity,再按下Back键自然会退出程序。
singleIntance模式的原理示意图: