四種啟動模式
- standard(默認)
- singleTop
- singleTast
- singleInstance
standard(默認)
系統默認的啟動模式。
Android是使用返回棧來管理活動的,在standard模式下,每當啟動一個新的活動,它就會在返回棧中入棧,並處於棧頂的位置。
對於使用standard模式的活動,系統不會在乎這個活動是否已經在返回棧中存在,而是每次啟動活動都會創建該活動的一個新的實例。
MainActivity.java:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("Data", this.toString());
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this, MainActivity.class);
startActivity(intent);
}
});
}
連續點擊兩次按鈕,LogCat信息如下:
從日志中可以看出,每點擊一次Activity就會創建出一個新的MainActivity實例,此時在棧中也會存在三個MainActivity實例,所以如果需要退出程序的話需要連續點擊三次Back鍵才能退出
standard模式原理示意圖:
singleTop
android:launchMode="singleTop"
當活動的啟動模式指定為singleTop,在啟動活動時,如果發現該返回棧的棧頂已經是該活動時,則認為可以直接使用它,不會在創建新的活動實例
然后MainActivity點擊按鈕啟動修改為SecondActivity
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
SecondActivity.java:
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.d("Data", this.toString());
setContentView(R.layout.second_layout);
Button button = (Button) findViewById(R.id.button_2);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(SecondActivity.this, MainActivity.class);
startActivity(intent);
}
});
}
返回棧棧頂活動:MainActivity --> SecondActivity -->MainActivity
在SecondActivity中啟動MainActivity,因為棧頂活動變成了SecondActivity,所以會創建一個新的MainActivity實例。按Back鍵返回到SecondActivity,再按一個Back返回到MainActivity,再次按Back才會退出程序
singleTop模式原理示意圖:
singleTask
當活動的啟動模式指定為singleTask,每次啟動該活動時,首先會在返回棧中檢查是否存在該活動的實例,如果發現已經存在就直接使用該實例,並把這個活動之上的所有活動統統出棧,如果沒有發現就會創建一個新的活動實例。
android:launchMode="singleTask"
在MainActivity中添加onRestart()方法,並打印日志:
@Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Log.d("Data", "onRestart_MainActivity");
}
在SecondActivity中添加onDestroy()方法,並打印日志:
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.d("Data", "onDestroy_SecondActivity");
}
在 FirstActivity 界面點擊按鈕進入到 SecondActivity,然后在SecondActivity 界面點擊按鈕,又會重新進入到 FirstActivity,日志如下:
在 SecondActivity 中啟動 FirstActivity 時,會發現返回棧中已經存在一個 FirstActivity 的實例,並且是在 SecondActivity 的下面,於是 SecondActivity 會從返回棧中出棧,而 FirstActivity 重新成為了棧頂活動,因此FirstActivity 的 onRestart()方法和 SecondActivity 的 onDestroy()方法會得到執行。 現在返回棧中應該只剩下一個 FirstActivity 的實例了,按一下 Back 鍵就可以退出程序。
singleTask原理示意圖:
singleInstance
指定為singleInstance模式的活動會啟用一個新的返回棧來管理這個活動,不管是哪個應用程序來訪問這個活動,都共用的同一個返回棧,解決了共享活動實例的問題
修改SecondActivity的啟動模式
android:launchMode="singleInstance"
修改MainActivity中onCreate()方法中的Log.d()方法,打印返回棧的ID
Log.d("Data", "MainActivity Task id is "+getTaskId());
修改SecondActivity:
Log.d("Data", "SecondActivity Task id is "+getTaskId());
Intent intent = new Intent(SecondActivity.this, ThirdActivity.class);
ThirdActivity:
Log.d("Data", "ThirdActivity Task id is "+getTaskId());
日志如下:
由此可看出SecondActivity的ID不同其他兩個Activity,這說明SecondActivity存放在一個單獨的返回棧中,這個棧中只有SecondActivity活動
singleInstance模式示意圖
注:文中內容和模式示意圖來自於郭霖大神的《第一行代碼》