Android日常開(kāi)發(fā)中,總是離不開(kāi)Activity;說(shuō)起Activity那就避不開(kāi)Activity啟動(dòng)模式(launchMode)。
Activity的四種啟動(dòng)模式:
- standard:
- singleTop:
- singleTask:
- singleInstance:
我們都知道2,3,4這幾種情況,如果Activity棧中有相應(yīng)的實(shí)例,則直接重用該實(shí)例而不需要new。重用時(shí)會(huì)調(diào)用該實(shí)例的onNewIntent(),讓該實(shí)例回到棧頂,并將其上面的其他實(shí)例退出棧。
我們從源碼角度來(lái)看一下onNewIntent():
/**
* This is called for activities that set launchMode to "singleTop" in
* their package, or if a client used the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP}
* flag when calling {@link #startActivity}. In either case, when the
* activity is re-launched while at the top of the activity stack instead
* of a new instance of the activity being started, onNewIntent() will be
* called on the existing instance with the Intent that was used to
* re-launch it.
*
* <p>An activity will always be paused before receiving a new intent, so
* you can count on {@link #onResume} being called after this method.
*
* <p>Note that {@link #getIntent} still returns the original Intent. You
* can use {@link #setIntent} to update it to this new Intent.
*
* @param intent The new intent that was started for the activity.
*
* @see #getIntent
* @see #setIntent
* @see #onResume
*/
protected void onNewIntent(Intent intent) {
}
It's clear that 該方法的注釋是關(guān)鍵,初級(jí)英語(yǔ)你可以的...
下面來(lái)談一下過(guò)程:
- 如果Activity第一次啟動(dòng),則執(zhí)行序列:
onCreate() ---> onStart() --->onResume() ....and so on...
- 如果Activity棧有該實(shí)例(啟動(dòng)模式2,3,4),則執(zhí)行序列:
onNewIntent() ---> onRestart() ---> onStart() ---> onResume...
- 如果android系統(tǒng)由于內(nèi)存不足把已存在Activity釋放掉,則只能重新啟動(dòng)Activity,即執(zhí)行:
onCreate() ---> onStart() ---> onResume() ... and so on...
注意事項(xiàng)
- 當(dāng)我們把當(dāng)前Activity置于后臺(tái)(不啟動(dòng)其他Activity),再切換至前臺(tái),其執(zhí)行序列為:
onRestart() ---> onStart() ---> onResume()...
- 當(dāng)我們?cè)诋?dāng)前Activity,彈出對(duì)話框orToast,將不會(huì)對(duì)Activity的生命周期產(chǎn)生任何影響。下面是源碼中AlertDialog的show()的實(shí)現(xiàn):
/**
* Start the dialog and display it on screen. The window is placed in the
* application layer and opaque. Note that you should not override this
* method to do initialization when the dialog is shown, instead implement
* that in {@link #onStart}.
*/
public void show() {
if (mShowing) {
if (mDecor != null) {
if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
}
mDecor.setVisibility(View.VISIBLE);
}
return;
}
mCanceled = false;
if (!mCreated) {
dispatchOnCreate(null);
} else {
// Fill the DecorView in on any configuration changes that
// may have occured while it was removed from the WindowManager.
final Configuration config = mContext.getResources().getConfiguration();
mWindow.getDecorView().dispatchConfigurationChanged(config);
}
onStart();
/**mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);*/
mDecor = mWindow.getDecorView();
if (mActionBar == null && mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
final ApplicationInfo info = mContext.getApplicationInfo();
mWindow.setDefaultIcon(info.icon);
mWindow.setDefaultLogo(info.logo);
mActionBar = new WindowDecorActionBar(this);
}
WindowManager.LayoutParams l = mWindow.getAttributes();
if ((l.softInputMode
& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) == 0) {
WindowManager.LayoutParams nl = new WindowManager.LayoutParams();
nl.copyFrom(l);
nl.softInputMode |=
WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
l = nl;
}
/**這句話是關(guān)鍵,AlertDialog的本質(zhì)就是:
* windowManager.addView(mWindow.getDecorView(),mWindow.getAttribute())
*/
mWindowManager.addView(mDecor, l);
mShowing = true;
/**通過(guò)發(fā)送Message,通知Handler來(lái)做相應(yīng)處理**/
sendShowMessage();
}
通過(guò)上述的Source Code,We will be find that AlertDialog的本質(zhì)就是通過(guò)WindowManager.addView()來(lái)實(shí)現(xiàn)的,所以對(duì)Activity的生命周期有毛的影響...
如果你此時(shí)對(duì)Activity Lifecycle產(chǎn)生了質(zhì)疑,Please click here,我還是怕沒(méi)人點(diǎn)啊。
onPause() --- Called when the system is about to start resuming a previous activity(當(dāng)系統(tǒng)將要開(kāi)始顯示另一個(gè)Activity時(shí)調(diào)用).
立帖為證,回頭寫個(gè)Dialog的源碼分析...
總結(jié)
- 除了startand模式外,無(wú)論采用什么模式,只有activity時(shí)同一個(gè)實(shí)例,且Intent發(fā)生了變化,即啟動(dòng)了其他Activity,才會(huì)觸發(fā)onNewIntent()方法。
- 使用onNewIntent()方法時(shí),需要在onNewIntent()中使用setIntent(intent)賦值給Activity的Intent,否則,我們只能得到以前的Intent.(詳見(jiàn)onNewIntent()源碼的注釋)

經(jīng)測(cè)試會(huì)發(fā)現(xiàn),onNewIntent()的參數(shù)intent是最新的Intent,我們?nèi)绻徽{(diào)用setIntent,就需要本地自己維護(hù)該Activity的Intent啦。(推薦使用onNewIntent())
3.無(wú)意中測(cè)試發(fā)現(xiàn),AlertDialog和Toast將不會(huì)影響Activity的Lifecycle。(實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn)...)
歡迎留言...期待指導(dǎo)...