上一篇我们分析了Activity的启动流程,由于代码量很大,还是没有分析的很详细,但是基本流程都出来了,更详细的东西还是要去看源码,源码在我文章的最后有给出,里面有我添加的详细的注释。这一章来分析Activity的finish过程,这个问题在两年前我去面试金山的时候曾经被问到过,那时候对源码基本没什么了解,所以当时根本是不了解的,今天我们就来分析一下finish的过程到底做了哪些处理,最后对Activity的整个启动过程以及finish过程绘制流程图,以方便我们记忆。
finish代码分析 首先先贴一张时序图:
Activity的finish方法就是调用的父类的finish方法:
Step1.Activity.finish 1 2 3 public void finish () { finish(DONT_FINISH_TASK_WITH_ACTIVITY); }
这里调用finish方法,传入参数DONT_FINISH_TASK_WITH_ACTIVITY,这个参数是在finish掉Activity的时候不finish掉Task。
Step2.Activity.finish 1 2 3 4 5 6 7 8 private void finish (int finishTask) { ... if (ActivityManagerNative.getDefault() .finishActivity(mToken, resultCode, resultData, finishTask)) { mFinished = true ; } ... }
ActivityManagerNative.getDefault()方法其实我们在前面文章提到过,得到的是AMP(ActivityManagerProxy)。
Step3.AMP.finishActivity 1 2 3 4 5 6 public boolean finishActivity (IBinder token, int resultCode, Intent resultData, int finishTask) throws RemoteException { ... mRemote.transact(FINISH_ACTIVITY_TRANSACTION, data, reply, 0 ); ... }
通过Binder调用AMS的finishActivity方法。
Step4.AMS.finishActivity 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public final boolean finishActivity (IBinder token, int resultCode, Intent resultData, int finishTask) { ... synchronized (this ) { ActivityRecord r = ActivityRecord.isInStackLocked(token); if (r == null ) { return true ; } TaskRecord tr = r.task; ActivityRecord rootR = tr.getRootActivity(); ... if (mController != null ) { ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0 ); if (next != null ) { ... } } final long origId = Binder.clearCallingIdentity(); try { final boolean finishWithRootActivity = finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY; if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY || (finishWithRootActivity && r == rootR)) { res = removeTaskByIdLocked(tr.taskId, false , finishWithRootActivity); ... } else { res = tr.stack.requestFinishActivityLocked(token, resultCode, resultData, "app-request" , true ); ... } return res; } finally { ... } } }
上面try语句中会走else语句中的方法也就是ActivityStack.requestFinishActivityLocked
Step5.ActivityStack.requestFinishActivityLocked 1 2 3 4 5 6 7 8 final boolean requestFinishActivityLocked (IBinder token, int resultCode, Intent resultData, String reason, boolean oomAdj) { ActivityRecord r = isInStackLocked(token); ... finishActivityLocked(r, resultCode, resultData, reason, oomAdj); return true ; }
调用finishActivityLocked方法
Step6.ActivityStack.finishActivityLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 final boolean finishActivityLocked (ActivityRecord r, int resultCode, Intent resultData, String reason, boolean oomAdj) { if (r.finishing) { Slog.w(TAG, "Duplicate finish request for " + r); return false ; } r.makeFinishingLocked(); ... r.pauseKeyDispatchingLocked(); adjustFocusedActivityLocked(r, "finishActivity" ); finishActivityResultsLocked(r, resultCode, resultData); final boolean endTask = index <= 0 ; final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE; if (mResumedActivity == r) { ... if (mPausingActivity == null ) { startPausingLocked(false , false , null , false ); } if (endTask) { mStackSupervisor.removeLockedTaskLocked(task); } } else if (r.state != ActivityState.PAUSING) { ... return finishCurrentActivityLocked(r, (r.visible || r.nowVisible) ? FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE, oomAdj) == null ; } else { ... } return false ; }
这里首先调用ActivityRecord.makeFinishingLocked标记开始结束Activity,然后调用ActivityRecord.pauseKeyDispatchingLocked方法停止键盘事件分发。然后调用adjustFocusedActivityLocked方法,调整Activity的焦点状体。
Step7.ActivityStack.adjustFocusedActivityLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 private void adjustFocusedActivityLocked (ActivityRecord r, String reason) { if (!mStackSupervisor.isFocusedStack(this ) || mService.mFocusedActivity != r) { return ; } final ActivityRecord next = topRunningActivityLocked(); final String myReason = reason + " adjustFocus" ; if (next != r) { if (next != null && StackId.keepFocusInStackIfPossible(mStackId) && isFocusable()) { mService.setFocusedActivityLocked(next, myReason); return ; } else { final TaskRecord task = r.task; if (r.frontOfTask && task == topTask() && task.isOverHomeStack()) { final int taskToReturnTo = task.getTaskToReturnTo(); if (!mFullscreen && adjustFocusToNextFocusableStackLocked(taskToReturnTo, myReason)) { return ; } if (mStackSupervisor.moveHomeStackTaskToTop(taskToReturnTo, myReason)) { return ; } } } } mService.setFocusedActivityLocked(mStackSupervisor.topRunningActivityLocked(), myReason); }
当前Activity要finish掉,就找找到下一个应该获取焦点的Activity,在该Activity被finish掉之后显示出来。
Step8.ActivityStack.finishActivityResultsLocked 1 2 3 4 5 6 7 8 9 10 11 12 final void finishActivityResultsLocked (ActivityRecord r, int resultCode, Intent resultData) { ActivityRecord resultTo = r.resultTo; if (resultTo != null ) { ... resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode, resultData); r.resultTo = null ; } else if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "No result destination from " + r); ... }
如果要接收Result的Activity描述对象ActivityRecord还存在,就将result相关信息封装成ActivityResult对象放到ActivityResult列表中保存起来。然后置空该Activity对应的ActivityRecord对象中的信息。
Step9.ActivityStack.startPausingLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 final boolean startPausingLocked (boolean userLeaving, boolean uiSleeping, ActivityRecord resuming, boolean dontWait) { if (mPausingActivity != null ) { Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity + " state=" + mPausingActivity.state); if (!mService.isSleepingLocked()) { completePauseLocked(false , resuming); } } ActivityRecord prev = mResumedActivity; if (prev == null ) { if (resuming == null ) { Slog.wtf(TAG, "Trying to pause when nothing is resumed" ); mStackSupervisor.resumeFocusedStackTopActivityLocked(); } return false ; } if (mActivityContainer.mParentActivity == null ) { mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, dontWait); } ... prev.state = ActivityState.PAUSING; ... final ActivityRecord next = mStackSupervisor.topRunningActivityLocked(); ... if (prev.app != null && prev.app.thread != null ) { ... prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing, userLeaving, prev.configChangeFlags, dontWait); ... } else { ... } ... }
这里主要是在finish之前pause该Activity,如果状态正常会调用schedulePauseActivity方法,最终调用Activity的onPause方法,这个过程我们在前面讲过几次了,这里就不再分析,比较简单。我们接着看核心的代码。
Step10.ActivityStack.finishCurrentActivityLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 final ActivityRecord finishCurrentActivityLocked (ActivityRecord r, int mode, boolean oomAdj) { final ActivityRecord next = mStackSupervisor.topRunningActivityLocked(); if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible) && next != null && !next.nowVisible) { if (!mStackSupervisor.mStoppingActivities.contains(r)) { addToStopping(r, false ); } ... return r; } ... final ActivityState prevState = r.state; r.state = ActivityState.FINISHING; final boolean finishingActivityInNonFocusedStack = r.task.stack != mStackSupervisor.getFocusedStack() && prevState == ActivityState.PAUSED && mode == FINISH_AFTER_VISIBLE; if (mode == FINISH_IMMEDIATELY || (prevState == ActivityState.PAUSED && (mode == FINISH_AFTER_PAUSE || mStackId == PINNED_STACK_ID)) || finishingActivityInNonFocusedStack || prevState == ActivityState.STOPPED || prevState == ActivityState.INITIALIZING) { ... boolean activityRemoved = destroyActivityLocked(r, true , "finish-imm" ); ... return activityRemoved ? null : r; } ... return r; }
这里是开始销毁Activity,首先要保存状态,然后标记开始finish,然后调用destroyActivityLocked方法开始销毁。
Step11.ActivityStack.destroyActivityLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 final boolean destroyActivityLocked (ActivityRecord r, boolean removeFromApp, String reason) { ... cleanUpActivityLocked(r, false , false ); final boolean hadApp = r.app != null ; if (hadApp) { ... boolean skipDestroy = false ; try { r.app.thread.scheduleDestroyActivity(r.appToken, r.finishing, r.configChangeFlags); } catch (Exception e) { ... } ... return removedFromHistory; }
这里主要有两部操作,第一步是cleanUpActivityLocked,第二步是scheduleDestroyActivity。我们先看第一步。
Step12.ActivityStack.cleanUpActivityLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 final void cleanUpActivityLocked (ActivityRecord r, boolean cleanServices, boolean setState) { if (mResumedActivity == r) { mResumedActivity = null ; } if (mPausingActivity == r) { mPausingActivity = null ; } mService.resetFocusedActivityIfNeededLocked(r); ... mStackSupervisor.mFinishingActivities.remove(r); mStackSupervisor.mWaitingVisibleActivities.remove(r); ... if (cleanServices) { cleanUpActivityServicesLocked(r); } ... }
这里主要是将指向该销毁的Activity的引用都置空,进行释放,然后将该Activity描述对象从列表中移除该对象,最后是判断是否清理服务,其实主要是绑定该Activity的服务,如果有绑定则解除绑定。
Step13.ActivityManagerService.resetFocusedActivityIfNeededLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 final void resetFocusedActivityIfNeededLocked (ActivityRecord goingAway) { ... if (setFocusedActivityLocked( focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded" )) { return ; } ... }
这里调用setFocusedActivityLocked方法判断该Activity是不是允许允许将焦点移除。
Step14.ActivityManagerService.setFocusedActivityLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 boolean setFocusedActivityLocked (ActivityRecord r, String reason) { if (r == null || mFocusedActivity == r) { return false ; } if (!r.isFocusable()) { return false ; } ... final ActivityRecord last = mFocusedActivity; mFocusedActivity = r; if (r.task.isApplicationTask()) { if (mCurAppTimeTracker != r.appTimeTracker) { ... } else { startTimeTrackingFocusedActivityLocked(); } } else { r.appTimeTracker = null ; } ... if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity" )) { mWindowManager.setFocusedApp(r.appToken, true ); } ... return true ; }
这里看一下注释,主要是判断该Activity是否有焦点,是否允许切换焦点。因此要结束的Activity就要把焦点释放掉。
Step15.ActivityStack.cleanUpActivityServicesLocked 1 2 3 4 5 6 7 8 9 10 11 final void cleanUpActivityServicesLocked (ActivityRecord r) { if (r.connections != null ) { Iterator<ConnectionRecord> it = r.connections.iterator(); while (it.hasNext()) { ConnectionRecord c = it.next(); mService.mServices.removeConnectionLocked(c, null , r); } r.connections = null ; } }
上面我们提到这个方法主要是释放绑定的服务,如果没有则不需要释放。下面我们回到Step11中提到的第二步。
Step16.ApplicationThreadNative.scheduleDestroyActivity 1 2 3 4 5 6 7 public final void scheduleDestroyActivity (IBinder token, boolean finishing, int configChanges) throws RemoteException { ... mRemote.transact(SCHEDULE_FINISH_ACTIVITY_TRANSACTION, data, null , IBinder.FLAG_ONEWAY); .. }
这个很熟悉了。
Step17.ApplicationThread.scheduleDestroyActivity 1 2 3 4 5 public final void scheduleDestroyActivity (IBinder token, boolean finishing, int configChanges) { sendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0 , configChanges); }
通过发送消息到Handler中来处理。
Step18.ActivityThread.H.handleMessage 1 2 3 4 5 6 7 8 9 10 public void handleMessage (Message msg) { switch (msg.what) { ... case DESTROY_ACTIVITY: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy" ); handleDestroyActivity((IBinder) msg.obj, msg.arg1 != 0 , msg.arg2, false ); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break ; ...
Step19.ActivityThread.handleDestroyActivity 1 2 3 4 5 6 7 8 9 10 11 12 13 14 private void handleDestroyActivity (IBinder token, boolean finishing, int configChanges, boolean getNonConfigInstance) { ActivityClientRecord r = performDestroyActivity(token, finishing, configChanges, getNonConfigInstance); ... if (finishing) { try { ActivityManagerNative.getDefault().activityDestroyed(token); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } mSomeActivitiesChanged = true ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 private ActivityClientRecord performDestroyActivity (IBinder token, boolean finishing, int configChanges, boolean getNonConfigInstance) { ActivityClientRecord r = mActivities.get(token); Class<? extends Activity > activityClass = null ; if (localLOGV) Slog.v(TAG, "Performing finish of " + r); if (r != null ) { ... performPauseActivityIfNeeded(r, "destroy" ); ... try { r.activity.mCalled = false ; mInstrumentation.callActivityOnDestroy(r.activity); ... } catch (SuperNotCalledException e) { throw e; } catch (Exception e) { ... } } ... return r; }
执行performPauseActivityIfNeeded,然后执行Instrumentation.callActivityOnDestroy方法结束。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 private void performPauseActivityIfNeeded (ActivityClientRecord r, String reason) { if (r.paused) { return ; } try { r.activity.mCalled = false ; mInstrumentation.callActivityOnPause(r.activity); ... } catch (SuperNotCalledException e) { throw e; } catch (Exception e) { ... } r.paused = true ; }
如果已经paused了,则直接返回,否则调用Instrumentation.callActivityOnPause方法。
Step22.Instrumentation.callActivityOnPause 1 2 3 public void callActivityOnPause (Activity activity) { activity.performPause(); }
1 2 3 4 5 final void performPause () { .. onPause(); ... }
Step24.Activity.onPause 1 2 3 4 5 protected void onPause () { if (DEBUG_LIFECYCLE) Slog.v(TAG, "onPause " + this ); getApplication().dispatchActivityPaused(this ); mCalled = true ; }
这里就是调用了Activity的onPause方法了。
1 2 3 4 5 6 7 8 9 10 11 12 final void performStop (boolean preserveWindow) { ... if (!mStopped) { ... mCalled = false ; mInstrumentation.callActivityOnStop(this ); ... } mResumed = false ; }
这里调用Instrumentation.callActivityOnStop方法,这里本来还有Fragment的处理,我略掉了,自己看看。
Step26.Instrumentation.callActivityOnStop 1 2 3 public void callActivityOnStop (Activity activity) { activity.onStop(); }
这里调用了Activity的onStop方法。代码略了。
Step28.Instrumentation.callActivityOnDestroy 1 2 3 4 5 6 7 public void callActivityOnDestroy (Activity activity) { ... activity.performDestroy(); ... }
调用Activity的performDestroy方法
1 2 3 4 5 final void performDestroy () { ... onDestroy(); ... }
这里终于看到了onDestroy方法。这里还有Fragment的处理,我没有显示出来,自己看看。我们再回到Step20中的第二个方法中。
Step31.AMP.activityDestroyed 1 2 3 4 5 6 7 8 9 10 public void activityDestroyed (IBinder token) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(token); mRemote.transact(ACTIVITY_DESTROYED_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); reply.readException(); data.recycle(); reply.recycle(); }
然后调用AMS中的activityDestroyed方法。
Step32.AMS.activityDestroyed 1 2 3 4 5 6 7 8 public final void activityDestroyed (IBinder token) { synchronized (this ) { ActivityStack stack = ActivityRecord.getStackLocked(token); if (stack != null ) { stack.activityDestroyedLocked(token, "activityDestroyed" ); } } }
Step33.ActivityStack.activityDestroyedLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 final void activityDestroyedLocked (IBinder token, String reason) { final long origId = Binder.clearCallingIdentity(); try { ActivityRecord r = ActivityRecord.forTokenLocked(token); ... if (isInStackLocked(r) != null ) { if (r.state == ActivityState.DESTROYING) { cleanUpActivityLocked(r, true , false ); removeActivityFromHistoryLocked(r, null , reason); } } mStackSupervisor.resumeFocusedStackTopActivityLocked(); } finally { Binder.restoreCallingIdentity(origId); } }
这里主要是两步,第一个是调用cleanUpActivityLocked方法,清理Activity,前面Step12我们分析过了,不再分析。然后是调用removeActivityFromHistoryLocked方法,就是将该结束的Activity从历史列表中删除.
Step35.ActivityStack.removeActivityFromHistoryLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 private void removeActivityFromHistoryLocked ( ActivityRecord r, TaskRecord oldTop, String reason) { mStackSupervisor.removeChildActivityContainers(r); finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null ); ... if (task != null && task.removeActivity(r)) { if (mStackSupervisor.isFocusedStack(this ) && task == topTask && task.isOverHomeStack()) { mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo(), reason); } removeTask(task, reason); } cleanUpActivityServicesLocked(r); r.removeUriPermissionsLocked(); }
调用finishActivityResultsLocked方法处理Result,前面提到了。调用ActivityStackSupervisor.moveHomeStackTaskToTop将Home属性的Activity所在任务栈放到顶部。调用cleanUpActivityServicesLocked清理绑定的服务。
Step39.ActivityStackSupervisor.resumeFocusedStackTopActivityLocked 1 2 3 boolean resumeFocusedStackTopActivityLocked () { return resumeFocusedStackTopActivityLocked(null , null , null ); }
这里我们在上一章Activity的启动时已经分析过了。这里不再分析。到这里Activity的finish就分析完了,从这里我们主要学到的是finish的过程,以及finish过程中系统做了哪些处理,我们在写代码过程中应该做那些处理。
流程图:
代码地址: 直接拉取导入开发工具(Intellij idea或者Android studio)
Android_Framework_Source
注 Android开发群:192508518
微信公众账号:Code-MX
注:本文原创,转载请注明出处,多谢。