前言 在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 = https://www.it610.com/article/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方法有个返回值,通常有三种情况:
- true:当前事件不在向外传播
- false:当前时间继续向外传播
- super.onKeyDown,默认的流程,如果你需要屏蔽返回键,就不能这样返回
区别
onBackPressed和onKeyDown都可以用来屏蔽返回键,那有什么区别呢? 当onKeyDown返回true或者false时,会屏蔽onBackPressed方法的执行, 只有在默认的返回情况下爱,onBackPressed方法才会被执行到。