Finish和OnBackPressed、OnDestroy的區別

開發的過程中,常常見到finish()和onBackPressed()以及ondestory好像都能關掉Activity。自己抽空總結一下,首先看源碼,源碼基於'androidx.appcompat:appcompat:1.1.0'來分析。

1.Finish

android.app.Activity中源碼:
    @Override
    public void finish() {
        //關閉activity但不關閉棧
        finish(DONT_FINISH_TASK_WITH_ACTIVITY);
    }

    public void finishAndRemoveTask() {
        //如果當前activity是處於棧底,則關閉activity的同時關閉棧
        finish(FINISH_TASK_WITH_ROOT_ACTIVITY);
    }


    /**
     * 完成當前活動並指定是否刪除與此活動關聯的任務。
     */
    private void finish(int finishTask) {
        if (mParent == null) {
            int resultCode;
            Intent resultData;
            synchronized (this) {
                resultCode = mResultCode;
                resultData = mResultData;
            }
            if (false) Log.v(TAG, "Finishing self: token=" + mToken);
            try {
                if (resultData != null) {
                    // 準備此{@link Intent}以退出應用程序進程。
                    resultData.prepareToLeaveProcess(this);
                }
                // 1、猜測更具finish的類別finishTask進行關閉
                // 退回上一個Activity,並且會將resultCode, resultData返回。如果啓動的是startActivityForResult將會在onActivityResult響應
                if (ActivityManager.getService().finishActivity(mToken, resultCode, resultData, finishTask)) {
                    mFinished = true;
                }
            } catch (RemoteException e) {
                // Empty
            }
        } else {//如果有嵌套的父級Activity,則在父級activity關閉,此時childActivity會被自動銷燬。
            mParent.finishFromChild(this);
        }

        //如果Intent中帶有要保存UI信息,則應該保存mInten中的信息
        if (mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)) {
            getAutofillManager().onPendingSaveUi(AutofillManager.PENDING_UI_OPERATION_RESTORE, mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN));
        }
    }

2.OnDestroy

  androidx.appcompat.app.AppCompatActivity中的源碼
  @Override
    protected void onDestroy() {
        super.onDestroy();
        getDelegate().onDestroy();
    }
    
   
    androidx.fragment.app.FragmentActivity中的源碼
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //關閉可能包含的Fragment
        mFragments.dispatchDestroy();
        //讓Lifecycle處於destory狀態
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
    }  

   android.app.Activity中的源碼
    /**
     * 1、在銷燬活動之前執行任何最後的清理。可以是人爲調用了finish,或者系統內存緊張調用了。
     * 2、不能在destory中保存數據,因爲系統將簡單地殺死活動的託管過程,即可能關閉程序ondestory不一定被調用了
     * 3、子類必須調用super.onDestory
     */
    @CallSuper
    protected void onDestroy() {
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this);
        mCalled = true;

        /**
         * 關閉當前Activity管理的所有dialog,所以diaolog 不應該使用applicationContext
         */
        if (mManagedDialogs != null) {
            final int numDialogs = mManagedDialogs.size();
            for (int i = 0; i < numDialogs; i++) {
                final ManagedDialog md = mManagedDialogs.valueAt(i);
                if (md.mDialog.isShowing()) {
                    md.mDialog.dismiss();
                }
            }
            mManagedDialogs = null;
        }

        // 關閉任何Cursors,所以cursor不應該用ApplicationContext初始化
        // 現在的版本比以前的低版本對內存泄漏的檢測和解決更加強大了
        synchronized (mManagedCursors) {
            int numCursors = mManagedCursors.size();
            for (int i = 0; i < numCursors; i++) {
                ManagedCursor c = mManagedCursors.get(i);
                if (c != null) {
                    c.mCursor.close();
                }
            }
            mManagedCursors.clear();
        }

        //關閉任何 searchDialog
        if (mSearchManager != null) {
            mSearchManager.stopSearch();
        }

        //關閉ActionBar
        if (mActionBar != null) {
            mActionBar.onDestroy();
        }

        //ActivityLifecycleCallbacks 取消生命週期回調監聽
        getApplication().dispatchActivityDestroyed(this);
    }

3.OnDestory

 androidx.activity.ComponentActivity中的源碼  
 public void onBackPressed() {
        mOnBackPressedDispatcher.onBackPressed();
 }

 androidx.activity.OnBackPressedDispatcher中的源碼
    /**
     * 1、只有最後按得back返回鍵,才能將OnBackPressedCallback 設置爲isEnabled=true
     * 2、舊版的OnbackPressed好分析一些
     * 3、隨着版本的更新,軟件內部的代碼結構和構造是不斷變化的
     */
    @MainThread
    public void onBackPressed() {
        Iterator<OnBackPressedCallback> iterator =
                mOnBackPressedCallbacks.descendingIterator();
        while (iterator.hasNext()) {
            OnBackPressedCallback callback = iterator.next();
            if (callback.isEnabled()) {
                callback.handleOnBackPressed();
                return;
            }
        }
        if (mFallbackOnBackPressed != null) {
            mFallbackOnBackPressed.run();
        }
    }

總結:

1、調用onBackPressed()方法不一定就能結束Activity。

2、調用onBackPressed()方法結束Activity,其調用的終究還是finish()方法。

3、finish()方法最後調用了Ondestory。

4、Android系統內存緊張時,可能會關閉軟件進程,此時Activity的該方法不一定必然被調用。


 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章