Android Activity的啟動模式(一)
Activity的四種LaunchMode
standard:標準模式
????standard是系統的默認啟動模式,每次啟動一個Activity都會重新創建一個實體,不管這個實體是否已經存在,這是一種典型的多實體實作,一個任務堆疊可以有多個實體,每個實體也可以屬于不同的任務堆疊,在這種模式下,誰啟動了這個Activity,那么這個Activity就運行在誰的Activity所在的堆疊中,
比如:ActivityA 啟動了Activity B(B是標準模式),那么B就會進入到A所在的堆疊中,
這樣就出現一個很容易忽視的問題,當我們用ApplicationContext去啟動一個standard模式的Activity時,會出現如下錯誤:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(TAG, "this is onStart");
mContext = getApplicationContext();
Intent intent = new Intent(this, SecondActivity.class);
mContext.startActivity(intent);
}
Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
at android.app.ContextImpl.startActivity(ContextImpl.java:1018)
at android.app.ContextImpl.startActivity(ContextImpl.java:994)
at android.content.ContextWrapper.startActivity(ContextWrapper.java:403)
at com.org.tcl.launchmodetest.MainActivity.onCreate(MainActivity.java:22)
這是因為standard模式的Activity默認會進入啟動它的Activity所屬的任務堆疊中,但是由于非Activity型別的Context并沒有所謂的任務堆疊,所以這就會報出錯誤,
解決這個問題的方法很簡單,啟動這個Activity的時候指定FLAG_ACTIVITY_NEW_TASK標記位,這樣在啟動這個Activity的時候就會為它創建一個新的任務堆疊,這就沒問題了,
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(TAG, "this is onCreate");
mContext = getApplicationContext();
Intent intent = new Intent(this, SecondActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
SingleTop:堆疊頂復用模式
????堆疊頂復用模式,顧名思義,在這種模式下:
????1. 如果新的Activity已經位于任務堆疊的堆疊頂,那么此Activity不會被重新創建,同時它得onNewIntent方法會被回呼,通過此方法的引數我們可以取出當前請求的資訊,需要注意的是,這個Activity的onCreate、onStart不會被系統呼叫,因為它并沒有發生改變,
????2. 如果新Activity的實體已經存在但是不是位于堆疊頂,那么新的Activity仍然會被重建,
????舉個例子,假設目前堆疊內的情況為ABCD,其中ABCD為4個Activity,A在堆疊底,D在堆疊頂,那么假設要再次啟動D,如果D的啟動模式是SingleTop,那么堆疊內情況還是ABCD,如果D的啟動模式是standard,那么堆疊內情況就變成了ABCDD,
SingleTask:堆疊內復用模式
????堆疊內復用模式,這是一種單實體模式,在這個模式下,只要Activity在一個堆疊中存在,那么多次啟動這個Activity都不會重新創建實體,和SingleTop一樣,這個也會呼叫onNewIntent方法,
????具體一點說,當一個具有singletask模式的Activity A請求啟動后,系統首先會尋找是否存在A想要的任務堆疊,如果不存在,就會重新創建一個任務堆疊,然后創建A的實體并將A放到這個堆疊中;如果存在A想要的任務堆疊,這時需要看A是否在堆疊中有實體存在,如果有實體存在,那么系統會將A調到堆疊頂并呼叫它的onNewIntent方法,如果實體不存在,就創建A的實體并把A壓入堆疊中,
????舉例說明一下:
- 比如目前任務堆疊S1 中的情況是ABC,這個時候Activity D以SingleTask的模式請求啟動,其所需要的任務堆疊是S2,由于S2和D都不存在,所以系統會先創建任務堆疊S2,然后再創建D的實體將D入堆疊到S2,
- 另外一種情況,假設D所需要的任務堆疊為S1,其他情況如上,那么由于S1已經存在,系統會直接創建D并將其入堆疊到S1中,
- 如果D所需的任務堆疊為S1,并且當前任務堆疊S1的情況為ADBC,那么根據堆疊內復用原則,此時D不會創建,系統會把D切換到堆疊頂并呼叫其onNewIntent方法,同時由于SingleTask默認具有clearTop的效果,會導致堆疊內所有在D上面的Activity全部出堆疊,于是最終S1中的情況變為AD,
SingleInstance:單實體模式
????單實體模式:這是一種加強的SingleTask模式,它除了具有SingleTask模式的所有特性之外,還加強了一點,那就是具有此種模式的Activity只能單獨的位于一個任務堆疊中,換句話說,如果Activity A是SingleInstance模式,當A啟動后,系統會它創建新的任務堆疊,然后A獨立的在這新的任務堆疊中,由于堆疊內復用的特性,后續的請求均不會創建新的Activity,除非這個特性的任務堆疊已經被系統銷毀了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/279834.html
標籤:其他
