finish(),用的最多的一个关闭当前activity的方法。
onBackPressed(),平时不怎么用,是android返回按钮调用的一个方法。
一般来说,这两个方法的作用是一致的。
但是在我使用共享变换的时候-Shared Element Transition
发现使用finish(),将无法实现返回上一层的共享变换,必须使用onBackPressed(),才能实现。
本文,主要从源码的角度探讨这两者的区别。
1、finish()
public void finish() {
finish(DONT_FINISH_TASK_WITH_ACTIVITY);
}
/** @hide Task isn't finished when activity is finished */
public static final int DONT_FINISH_TASK_WITH_ACTIVITY = 0;
/**
* @hide Task is finished if the finishing activity is the root of the task. To preserve the
* past behavior the task is also removed from recents.
*/
public static final int FINISH_TASK_WITH_ROOT_ACTIVITY = 1;
/**
* @hide Task is finished along with the finishing activity, but it is not removed from
* recents.
*/
public static final int FINISH_TASK_WITH_ACTIVITY = 2;
这里一共有三种,从注释上,我们看到,分别是:
0、关闭activity但不关闭栈
1、如果当前activity是处于栈底,则关闭activity的同时关闭栈
2、不管如果,关闭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) {
resultData.prepareToLeaveProcess(this);
}
if (ActivityManagerNative.getDefault()
.finishActivity(mToken, resultCode, resultData, finishTask)) {
mFinished = true;
}
} catch (RemoteException e) {
// Empty
}
} else {
mParent.finishFromChild(this);
}
}
上面的requestcode resultcode很明显是给startactivityforresult用的,忽略。
这里执行的就是直接关闭activity的方法。
ActivityManagerNative.getDefault().finishActivity(mToken, resultCode, resultData, finishTask)
关闭activity,同时将resultcode,resultdata,finish类别一起进行处理。
2、onBackPressed()
onBackPressed()的方法比较复杂了。
public void onBackPressed() {
if (mActionBar != null && mActionBar.collapseActionView()) {
return;
}
if (!mFragments.getFragmentManager().popBackStackImmediate()) {
finishAfterTransition();
}
}
其实到这里,我们就已经能知道为什么,onBackPressed()可以实现共享变换了。
onBackPressed方法,会先判断是否有弹出的窗口,popWindow,比如dialog,比如菜单,等等,如果有,先关闭这些。
如果没有再来进行关闭操作。
finishAfterTransition(),意思很直白,在执行完变换后再进行finish()。
我们点进去看看。
public void finishAfterTransition() {
if (!mActivityTransitionState.startExitBackTransition(this)) {
finish();
}
}
mActivityTransitionState.startExitBackTransition(this)
如果没有回退的共享变换,直接执行finish()。
3、总结
一共存在以下三种情况:
(1)没有弹框,没有菜单,没有共享变换—–该情况,finish和onBackPressed是完全一样的。
(2)存在弹框、菜单等—–该情况,onBackPressed要先关闭popWindow
(3)存在共享变化—–该情况,finish不会调用变换动画,必须使用onBackPressed方法。