上一篇博文介绍了启动Activity请求的流程以及对相关数据结构的处理,那么当我们试图结束Activity的时候,ActivityManagerService的行为将会是怎样的呢?这一节将介绍结束Activity的3种主要方法和4个阶段。
1.结束Activity的3种主要方法
结束Activity时,我们通常采用如下3种主要方法。
①以编程的方式结束Activity
该方法即在代码中显式调用Activity的finish()方法。一般来说,我们经常会遇到这样的需求——点击某个按钮退出界面,此时只需要在按钮的点击事件中添加finish()方法即可。finish()方法的代码如下所示,finish()内部默认调用finish(false):
private void finish(boolean 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(); } if (ActivityManagerNative.getDefault() .finishActivity(mToken, resultCode, resultData, finishTask)) { mFinished = true; } } catch (RemoteException e) { // Empty } } else { mParent.finishFromChild(this); } }
以上红色标注的为主要方法。
②按键盘(硬键盘或者软键盘)上Back键来结束Activity
这种情况下,不需要添加任何代码就可以结束Activity,但需要注意的是,并不是所有的设备都会有Back键。在未加定制的Android代码中,它为每个Activity界面提供了软键盘。
当单击此按钮的时候,系统将会通过回调onBackPressed()方法告知Activity Back按键已经按下。onBackPressed()方法的代码如下所示:
public void onBackPressed() { if (mActionBar != null && mActionBar.collapseActionView()) { return; } if (!mFragments.getFragmentManager().popBackStackImmediate()) { finishAfterTransition(); } }
finishAfterTransition()代码如下:
public void finishAfterTransition() { if (!mActivityTransitionState.startExitBackTransition(this)) { finish(); } }
通过上面的代码可知,onBackPressed()方法的本质还是一个finish()方法。当然,也可以屏蔽这种行为,只需要在我们自行实现的Activity的onBackPressed()方法中取消调用super.onBackPressed()即可,但是我们不建议这样做。
③使用Home键使当前显示的Activity消失,回到Launcher首页
与Back键一样,并不是所有的设备都会提供硬Home按键。在未加定制的Android代码中,它为每个Activity界面提供了软键盘。
通常,应用程序无法捕获Home键,除非强行捕获,但不建议这么做。这个键将会由PhoneWindowManager处理,具体代码如下:
void startDockOrHome(){ Intent dock=createHomeDockIntent(); if(dock!=null){ try{ mContext.startActivity(dock); return; }catch(ActivityNotFoundException e){ } } mContext.startActivity(mHomeIntent); }
最终,Android会以mHomeIntent去启动Launcher从而使得当前Activity退居后台,Launcher被重新显示出来。mHomeIntent是这样定义的:
mHomeIntent=new Intent(Intent.ACTION_MAIN,null); mHomeIntent.addCateGory(Intent.CATEGORY_HOME); mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);