在Android開發中,活動(Activity)的launchmode是一個非常重要的概念,通過合理的使用launchmode可以大幅度提升應用程序的性能和用戶體驗。但是,launchmode也是一個非常容易出現問題的地方,錯誤的使用launchmode會導致應用程序出現各種各樣的奇怪問題,因此,在使用launchmode的時候務必要非常小心謹慎。
一、Standard模式:活動隨意創建,任務隨意分配
當我們在應用程序中啟動一個新的活動時,通常情況下系統會在當前的任務中創建這個活動的實例,而這個活動會自動的被打開並顯示在屏幕中,如果我們多次啟動同一個活動,每次都會創建一個新的實例,並加入到任務棧中。
public class MainActivity extends Activity {
// 點擊按鈕,啟動SecondActivity
public void onButtonClick(View view) {
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);
}
}
public class SecondActivity extends Activity {
// ...
}
如果我們在MainActivity中點擊按鈕,啟動SecondActivity,並且不做任何處理,那麼系統會創建一個新的SecondActivity實例,並讓它顯示在屏幕中。此時,如果我們再次通過按鈕啟動SecondActivity,系統就會再次創建一個新的SecondActivity實例,並且加入到任務棧中。
這種模式下的特點是,每次啟動活動都會創建一個新的實例,並加入到任務棧中,因此,如果活動被多次啟動,就會出現多個實例共存的情況;同時,由於活動任意分配到任務棧中,因此,這種模式下的活動可以和其他應用程序的活動一起混合在任務棧中,從而導致系統無法精確的控制活動的生命周期。
二、SingleTop模式:活動頂部「單一」
SingleTop模式與Standard模式類似,區別在於當我們啟動一個活動時,如果這個活動已經位於任務棧的頂部,那麼系統不會重新創建這個活動的實例,而是會調用這個活動的onNewIntent()方法,將intent作為參數傳遞進來,這樣就可以避免創建多餘的實例,提高了整個應用程序的運行效率。
public class MainActivity extends Activity {
// 點擊按鈕,啟動SecondActivity
public void onButtonClick(View view) {
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("data", "hello");
startActivity(intent);
}
}
public class SecondActivity extends Activity {
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
String data = intent.getStringExtra("data");
// ...
}
}
如果我們在MainActivity中點擊按鈕,啟動SecondActivity,並且不做任何處理。此時,如果我們再次通過按鈕啟動SecondActivity,並且傳入不同的數據,那麼系統不會重新創建SecondActivity的實例,而是會將傳入的Intent作為參數傳遞給SecondActivity的onNewIntent()方法,這樣就可以避免了創建多個實例的問題。
需要注意的是,如果我們從其他活動跳轉到SecondActivity,那麼系統還是會創建一個新的SecondActivity實例,並且加入任務棧中。
三、SingleTask模式:返回棧「單一」
SingleTask模式是一種比較特殊的模式,其特點是,系統只會為這個活動創建一個實例,並將它放在由它自己構成的返回棧中。當我們啟動SingleTask模式的活動時,系統會調用這個活動的onCreate()方法,如果這個活動已經存在返回棧中,就不會再次創建新的實例,而是會移除這個實例上面的所有活動,並將棧頂元素作為目標活動,調用它的onNewIntent()方法,並將傳入的Intent作為參數傳遞給它。
public class MainActivity extends Activity {
// 點擊按鈕,啟動SecondActivity
public void onButtonClick(View view) {
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);
}
}
public class SecondActivity extends Activity {
// ...
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}
@Override
protected void onResume() {
super.onResume();
Intent intent = getIntent();
// ...
}
}
如果我們在MainActivity中點擊按鈕,啟動SecondActivity,並且不做任何處理,那麼系統會創建一個新的SecondActivity實例,並讓它顯示在屏幕中。此時,如果我們再次通過按鈕啟動SecondActivity,系統會發現SecondActivity已經存在返回棧中了,因此,會直接調用SecondActivity的onNewIntent()方法,並將傳入的Intent作為參數傳遞給它。
需要注意的是,進入SingleTask模式的活動,一旦被啟動,就會成為任務棧的根活動,這個任務棧中所有的其他活動都會在這個活動的上面。並且,啟動這個活動的時候,系統還會調用其所在任務棧中已存在的所有活動的onDestroy()方法,從而使得任務棧中只有這一個實例。
四、SingleInstance模式:單獨存在
SingleInstance模式是一種更加特殊的模式,這種模式下的活動會獨立於任務棧之外存在,並且系統會為它單獨創建一個返回棧,它是唯一一個位於這個返回棧中的活動,在這種情況下,這個活動的生命周期與其他模式下的活動是完全不同的。
public class MainActivity extends Activity {
// 點擊按鈕,啟動SecondActivity
public void onButtonClick(View view) {
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);
}
}
public class SecondActivity extends Activity {
// ...
}
在SingleInstance模式下,如果我們在MainActivity中點擊按鈕,啟動SecondActivity,並且不做任何處理,那麼系統會為SecondActivity創建一個新的實例,並將這個實例放入一個獨立的返回棧中。此時,如果我們再次通過按鈕啟動SecondActivity,系統會直接讓返回棧中原來的SecondActivity實例重新顯示在屏幕上,這個實例的狀態和我們第一次啟動它時創建的狀態完全一樣。
需要注意的是,如果我們從其他活動跳轉到SecondActivity,那麼系統還是會創建一個新的SecondActivity實例,並且加入任務棧中。
五、總結
總的來說,Android的各種launchmode模式都是為了讓我們更好的控制活動的生命周期,提高應用程序的運行效率和用戶體驗。合理的使用launchmode可以將應用程序的響應速度和啟動速度大幅度提升,但是,如果使用不當就會引發各種各樣的問題,因此,在使用launchmode的時候,一定要非常小心謹慎。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/291743.html