在实际的项目中,我们需要根据特定的需求为每个活动指定特定的启动模式,启动模式分为四种:standard;singleTop;singleTask;singleInstance。
1、standard(默认):每当启动一个新的活动时,都会在返回棧中入栈,并处于栈顶的位置。系统不会在乎这个活动是否已经在返回棧中存在,每次启动都会创建该活动的一个新的实例。
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
Log.d(log_Tag, "MainActivity = " + this.toString());
button1_1 = (Button)findViewById(R.id.button1_1);
button1_1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this,MainActivity.class);
startActivity(intent);
}
});
在MainActivity 中执行发送 按钮,调用MainActivity,从logcat 可以看到,没执行一次按钮,就会新生成一个MainActivity实例。如果需要退出,则需要多次执行退出按钮。
2、singleTop:在启动活动时如果发现返回棧的栈顶已经是该活动,则认为可以直接使用它,不会再创建新的活动实例。但当活动不是处于栈顶位置时,重新启动时还是会创建新的实例。
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
在AndroidManifest.xml 中对MainActivity 执行launchMode为singleTop,从logcat可以看到多次执行后不会生成新的实例。且执行一次退出就可以退出应用。
当MainActivity不在栈顶时:
button1_1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
}
});
将发送按钮的活动指向SecondActivity,再将SecondActivity 中的返回按钮指向Mainacti:
button2_1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(SecondActivity.this,MainActivity.class);
startActivity(intent);
}
});
可以看到从SecondActivity 返回至MainActivity时,由于Mainactivity不在栈顶,依然会创建新的实例。
当执行退出按钮时,之前启动的活动需要多次执行退出。
3、singleTask:每次启动活动时系统都会检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这个活动之上的所有活动统统出棧,如果没有发现就会创建一个新的活动实例。
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
首先,在AndroidManifest.xml将launchMode 设定singleTask,在MainActivity复写onRestart()方法,在SecondActivity中复写onDestroy()方法。
@Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Log.d(log_Tag, "FirstActivity onRestart");
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.d(log_tag, "SecondActivity onDestroy");
}
执行起来可以看到应用启动时启动了MainActivity,执行send按钮后创建了SecondActivity实例,再执行Secondactivity中的send按钮后可以看到MainActivity执行了onRestart()方法,Secondactivity执行了onDestroy()方法。然后执行MainActivity中的退出按钮就可以直接退出应用了。
说明,使用singleTask方式,不是处于栈顶的MainActivity被重新启动,SecondActivity被Destroy。
4、singleInstance:当活动启动时,系统会新增一个返回棧来管理这个活动,不管哪个应用来访问这个活动,都共用的同一个返回棧。
将SecondActivity 的启动模式改为singleInstance,MainActivity 启动SecondActivity,SecondActivity启动ThridActivity,并在每个活动的onCreate()方法中打印出taskid。
<activity
android:name=".SecondActivity"
android:launchMode="singleInstance"></activity>
MainActivity.onCreate()方法:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(log_Tag, "Frist Activity task = " + getTaskId());
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
Log.d(log_Tag, "MainActivity = " + this.toString());
button_send_1_1 = (Button)findViewById(R.id.button_send_1_1);
button_send_1_1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
}
});
button_quit_1_1 = (Button)findViewById(R.id.button_quit_1_1);
button_quit_1_1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
}
SecondActivity.onCreate()方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.d(log_tag, "Second Activity task = " + getTaskId());
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_second);
Log.d(log_tag, "SecondActivity = " + this.toString());
button_send_2_1 = (Button) findViewById(R.id.button_send_2_1);
button_send_2_1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(SecondActivity.this,
ThirdActivity.class);
startActivity(intent);
}
});
button_quit_2_1 = (Button) findViewById(R.id.button_quit_2_1);
button_quit_2_1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
}
ThirdActivity.onCreate()方法:
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
Log.d(log_tag, "Third Activity task = " + getTaskId());
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_third);
button_send_3_1 = (Button)findViewById(R.id.button_send_3_1);
button_send_3_1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(ThirdActivity.this,MainActivity.class);
startActivity(intent);
}
});
button_quit_3_1 = (Button)findViewById(R.id.button_quit_3_1);
button_quit_3_1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
}
从logcat来看,从MainActivity 启动到SecondActivity时,MainActivity 的taskid 为19,Secondactivity 的taskid为20,从SecondActivity 启动到ThridActivity时,ThridActivity的taskid为19,说明SecondActivity 启用了不同的返回栈。
且从ThridActivity执行退出按钮时,返回到了MainActivity,MainActivity执行退出时返回到了SecondActivity。
由于MainActivity与ThridActivity是存放在同一个返回棧中的活动,当ThridActivity从返回棧中出棧时,MainActivity就成为了栈顶活动被显示在界面上,但MainActivity从返回棧出棧时,该返回棧已经清空,于是就显示下一个返回棧的栈顶活动了,当SecondActivity执行退出时,所有的返回棧都已经空了,所以应用程序退出。