活動的啓動模式總共有四種,分別是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");
}
再重寫SecondActivity的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模式的原理示意圖: