关于屏蔽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方法才会被执行到。





 






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android中,我们可以通过重写Activity的onBackPressed()方法屏蔽返回的功能,代码如下: ``` @Override public void onBackPressed() { // 屏蔽返回 // super.onBackPressed(); // 如果需要默认的返回功能,需要注释掉这行代码 } ``` 对于HOME屏蔽,由于Android系统限制,我们无法屏蔽HOME的功能。但是我们可以监听HOME的按下事件,并在按下事件发生时做一些特定的操作,例如弹出对话框或者跳转到其他页面。代码如下: ``` private static final String SYSTEM_DIALOG_REASON_KEY = "reason"; private static final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey"; @Override public void onAttachedToWindow() { super.onAttachedToWindow(); // 监听HOME getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_HOME) { // HOME按下事件 return true; } return super.onKeyDown(keyCode, event); } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (!hasFocus) { // 如果Activity失去了焦点,则判断是否是HOME按下事件 Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); sendBroadcast(closeDialog); } } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); // 判断是否是HOME按下事件 String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY); if (SYSTEM_DIALOG_REASON_HOME_KEY.equals(reason)) { // HOME按下事件 } } ``` 需要注意的是,由于Android系统限制,无法屏蔽HOME的功能,因此以上代码只能监听HOME的按下事件,并在按下事件发生时做一些特定的操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值