關於屏蔽Android返回鍵的一些思考

前言

在Android開發中,有時候我們需要屏蔽掉系統的返回鍵,比如在閃屏頁面或者進行某些特定的操作時,通常的實現要如下兩種方式。

1.重寫Activity的onBackPressed方法,當系統檢測到你按下了返回鍵的時候會觸發這個方法,通常是我們手機的back鍵

@Override
    public void onBackPressed() {
//        super.onBackPressed();//要去掉這句,否則會結束當前Activity,無法起到屏蔽的作用
        //處理自己的邏輯
    }
爲什麼要去掉super.onBackPressed這句呢,因爲這句的功能默認就是調用當前Activity的finish方法,銷燬當前頁面,接下來我們去看看源碼裏做了什麼
我們進入到super裏面,此時來到了FragmentActivity,

 @Override
    public void onBackPressed() {
        if (!mFragments.getSupportFragmentManager().popBackStackImmediate()) {//判斷Fragment棧中是否還有Fragment
            super.onBackPressed();
        }
    }
FragmentActivity是用來管理Fragment的,裏面提供了一些API,我們如果想要管理Fragment,則必須繼承這個Activity,
這裏onBackPressed方法先做了一個判斷,判斷popBackStackImmediste()方法的返回值,如果爲false,則繼續執行父類的onBackPressed方法,我們看看popBackStackImmediate方法的定義,
 /**
     * Like {@link #popBackStack()}, but performs the operation immediately
     * inside of the call.  This is like calling {@link #executePendingTransactions()}
     * afterwards without forcing the start of postponed Transactions.
     * @return Returns true if there was something popped, else false.
     */
    public abstract boolean popBackStackImmediate();
這個方法的意思是立即彈出Fragment回退棧中的任務,返回true代表有Fragment彈出,false代表返回棧中已經清空了,這個時候可以調用父類的super.onBackPressed方法了。

public void onBackPressed() {
        if (mActionBar != null && mActionBar.collapseActionView()) {//判斷ActionBar上是否還有東西沒執行完
            return;
        }

        if (!mFragments.getFragmentManager().popBackStackImmediate()) {//判斷Fragment回退棧是否清空
            finishAfterTransition();
        }
    }

上面最終調用了finishAfterTransition方法

 /**
     * Reverses the Activity Scene entry Transition and triggers the calling Activity
     * to reverse its exit Transition. When the exit Transition completes,
     * {@link #finish()} is called. If no entry Transition was used, finish() is called
     * immediately and the Activity exit Transition is run.
     * @see android.app.ActivityOptions#makeSceneTransitionAnimation(Activity, android.util.Pair[])
     */
    public void finishAfterTransition() {
        if (!mActivityTransitionState.startExitBackTransition(this)) {//判斷Activity的退出動畫是否執行完成
            finish();
        }
    }
finishAfterTransition會判斷如果Activity的退出動畫執行完畢了,則調用finish方法
   /**
     * Call this when your activity is done and should be closed.  The
     * ActivityResult is propagated back to whoever launched you via
     * onActivityResult().
     */
    public void finish() {
        finish(DONT_FINISH_TASK_WITH_ACTIVITY);
    }
finish方法默認調用了帶參數的finish方法,
 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) {
                    resultData.prepareToLeaveProcess(this);
                }
                if (ActivityManager.getService()//通知ActivityManager去結束Activity
                        .finishActivity(mToken, resultCode, resultData, finishTask)) {
                    mFinished = true;
                }
            } catch (RemoteException e) {
                // Empty
            }
        } else {
            mParent.finishFromChild(this);
        }
    }

至此,我們就分析完了onBackPressed方法的執行流程。

2.onKeyDow方法
 @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount()== 0) {
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
這裏判斷按鍵類型是否是back,並且判斷按鍵數量,這是防止多次點擊,增強程序健壯性,我們看到onKeyDown方法有個返回值,通常有三種情況:
  1. true:當前事件不在向外傳播
  2. false:當前時間繼續向外傳播
  3. super.onKeyDown,默認的流程,如果你需要屏蔽返回鍵,就不能這樣返回

 區別

onBackPressed和onKeyDown都可以用來屏蔽返回鍵,那有什麼區別呢?
當onKeyDown返回true或者false時,會屏蔽onBackPressed方法的執行,
只有在默認的返回情況下愛,onBackPressed方法纔會被執行到。





 






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