1st-onNewIntent()

Android日常開(kāi)發(fā)中,總是離不開(kāi)Activity;說(shuō)起Activity那就避不開(kāi)Activity啟動(dòng)模式(launchMode)。

Activity的四種啟動(dòng)模式:

  1. standard:
  2. singleTop:
  3. singleTask:
  4. 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ò)程:

  1. 如果Activity第一次啟動(dòng),則執(zhí)行序列:

onCreate() ---> onStart() --->onResume() ....and so on...

  1. 如果Activity棧有該實(shí)例(啟動(dòng)模式2,3,4),則執(zhí)行序列:

onNewIntent() ---> onRestart() ---> onStart() ---> onResume...

  1. 如果android系統(tǒng)由于內(nèi)存不足把已存在Activity釋放掉,則只能重新啟動(dòng)Activity,即執(zhí)行:

onCreate() ---> onStart() ---> onResume() ... and so on...


注意事項(xiàng)
  1. 當(dāng)我們把當(dāng)前Activity置于后臺(tái)(不啟動(dòng)其他Activity),再切換至前臺(tái),其執(zhí)行序列為:

onRestart() ---> onStart() ---> onResume()...

  1. 當(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é)

  1. 除了startand模式外,無(wú)論采用什么模式,只有activity時(shí)同一個(gè)實(shí)例,且Intent發(fā)生了變化,即啟動(dòng)了其他Activity,才會(huì)觸發(fā)onNewIntent()方法。
  2. 使用onNewIntent()方法時(shí),需要在onNewIntent()中使用setIntent(intent)賦值給Activity的Intent,否則,我們只能得到以前的Intent.(詳見(jiàn)onNewIntent()源碼的注釋)

onNewItent()的坑

經(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)...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容