准备知识:
IdleHandler
它提供了一种机制,当主线程消息队列空闲时,会执行 IdleHandler 的回调方法。至于怎么算 “空闲”,我们可以看一下 MessageQueue.next() 方法。
Instrumentation
用于实现应用程序测试代码的基类。当在打开仪器的情况下运行时,这个类将在任何应用程序代码之前为您实例化,允许您监视系统与应用程序的所有交互。可以通过AndroidManifest.xml的标签描述该类的实现。
ActivityManager
该类提供与Activity、Service和Process相关的信息以及交互方法, 可以被看作是ActivityManagerService的辅助类。
ActivityManagerService
Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用程序的管理和调度等工作。
ActivityThread
管理应用程序进程中主线程的执行,根据Activity管理者的请求调度和执行activities、broadcasts及其相关的操作。
ActivityStack
负责单个Activity栈的状态和管理。
ActivityStackSupervisor
负责所有Activity栈的管理。内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三个Activity栈。其中,mHomeStack管理的是Launcher相关的Activity栈;mFocusedStack管理的是当前显示在前台Activity的Activity栈;mLastFocusedStack管理的是上一次显示在前台Activity的Activity栈。
ClientLifecycleManager
用来管理多个客户端生命周期执行请求的管理类。
一. Activity.finish()
通过该分析解释onPause和onResume调用的及时,onStop,onDestroy可能会延期10s调用
1.1 执行onPause()和回调
- Activity.finish(DONT_FINISH_TASK_WITH_ACTIVITY);
- 搭载了带参数的 finish() 方法。参数是 DONT_FINISH_TASK_WITH_ACTIVITY ,含义也很直白,不会销毁 Activity 所在的任务栈。
- 其中activity中利用 Binder 调用了 AMS.finishActivity() 方法
- ActivityManagerService.finishActivity(IBinder token, int resultCode, Intent resultData,int finishTask)
- ActivityStack.requestFinishActivityLocked()
- ActivityStack.requestFinishActivityLocked()
- ActivityStack.finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,String reason, boolean oomAdj, boolean pauseImmediately)
- r.makeFinishingLocked();// 前面会做重复 finish 的检测就是依赖这个值
- startPausingLocked(false, false, null, pauseImmediately);// 开始 pause mResumedActivity
- ActivityStack.startPausingLocked(boolean userLeaving, boolean uiSleeping,ActivityRecord resuming, boolean pauseImmediately)
- 第一步通过 ClientLifecycleManager 分发生命周期流程。
- 第二步是发送一个延时 500ms 的消息,等待一下 onPause 流程.但是如果第一步中在 500ms 内已经完成了流程,则会取消这个消息。所以这两步的最终逻辑其实是一致的。这里就直接看第一步。
- ClientLifecycleManager它会向主线程的 Handler H 发送 EXECUTE_TRANSACTION 事件,调用 XXXActivityItem 的 execute() 和 postExecute() 方法。execute() 方法中会 Binder 调用 ActivityThread 中对应的 handleXXXActivity() 方法。在这里就是 handlePauseActivity() 方法,其中会通过 Instrumentation.callActivityOnPause(r.activity) 方法回调 Activity.onPause() 。
- Instrumentation.callActivityOnPause(Activity activity)
- activity.performPause();Activity onPause()被执行。
- onPause() 方法就被执行了。但是流程没有结束,接着就该显示下一个 Activity 了。
小结:调用finish会立即执行当前Activity的onPause和下一个Activity的显示流程
1.2 执行finish()流程
- 前面刚刚说过会调用 PauseActivityItem 的 execute() 和 postExecute() 方法。execute() 方法回调了当前 Activity.onPause(),而 postExecute() 方法就是去寻找要显示的 Activity 。
- PauseActivityItem.postExecute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions)
- ActivityManager.getService().activityPaused(token);
- ActivityManagerService.activityPaused(IBinder token)
- ActivityStack.activityPausedLocked()
- mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r) ,移除的就是之前延迟 500ms 的消息。接着看 completePauseLocked() 方法。
- ActivityStack.ompletePauseLocked(boolean resumeNext, ActivityRecord resuming)
- 判断了 finishing 状态,还记得 finishing 在何处被赋值为 true 的吗?在 Activity.finish() -> AMS.finishActivity() -> ActivitySta
- ck.requestFinishActivityLocked() -> ActivityStack.finishActivityLocked() 方法中。所以接着调用的是 finishCurrentActivityLocked() 方法
- // 当前获取焦点的 mStackSupervisor.getFocusedStack(); // 恢复要显示的 activity mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null); 此时会标记10s的超时
- ActivityStack.finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj,String reason)
- mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)&& next != null && !next.nowVisible addToStopping
- mode == FINISH_IMMEDIATELY || (prevState == PAUSED && (mode == FINISH_AFTER_PAUSE || inPinnedWindowingMode()))|| finishingActivityInNonFocusedStack|| prevState == STOPPING|| prevState == STOPPED|| prevState == ActivityState.INITIALIZING
- ActivityStack.addToStopping
- 这些在等待销毁的 Activity 被保存在了 ActivityStackSupervisor 的 mStoppingActivities 集合中,它是一个 ArrayList 。
- 整个 finish 流程就到此为止了。前一个 Activity 被保存在了 ActivityStackSupervisor.mStoppingActivities 集合中,新的 Activity 被显示出来了。
小结:finish流程执行完成只是将该Activity放入待销毁的ArrayList 中
1.3 真正回调onStop,onDestroy
- ActivityThread.handleResumeActivity()
- handleResumeActivity() 方法是整个 UI 显示流程的重中之重,它首先会回调 Activity.onResume() , 然后将 DecorView 添加到 Window 上,其中又包括了创建 ViewRootImpl,创建 Choreographer,与 WMS 进行 Binder 通信,注册 vsync 信号,著名的 measure/draw/layout
- 完成最终的界面绘制和显示之后Looper.myQueue().addIdleHandler(new Idler())
- MessageQueue.next()
- 当新的 Activity 完成页面绘制并显示之后,主线程就可以停下歇一歇,来执行 IdleHandler 了。再回来 handleResumeActivity() 中来
- ActivityThread.handleResumeActivity()
- Idler implements MessageQueue.IdleHandler
- Idler. queueIdle()
- 调用 AMS.activityIdle()
- Idler. queueIdle()
- Idler implements MessageQueue.IdleHandler
- ActivityManagerService.activityIdle(IBinder token, Configuration config, boolean stopProfiling)
- ActivityStackSupervisor.activityIdleInternalLocked()
- stops 和 finishes 分别是要 stop 和 destroy 的两个 ActivityRecord 数组。stops 数组是通过 ActivityStackSuperVisor.processStoppingActivitiesLocked() 方法获取的
- ActivityStackSupervisor.processStoppingActivitiesLocked(ActivityRecord idleActivity, boolean remove, boolean processPausingActivities)
- 遍历的是ActivityStackSuperVisor 中的 mStoppingActivities 集合 。在前面分析 finish() 流程到最后的 addToStopping() 方法时提到过,
小结:MessageQueue.next() 中主线程完成后执行IdleHandler,去执行ArrayList中待销毁的Activity
1.4 为什么10s onStop/onDestroy:
- ActivityStackSuperVisor.resumeFocusedStackTopActivityLocked()
- ActivityStack.resumeTopActivityUncheckedLocked()
- ActivityStack.resumeTopActivityInnerLocked()
- ActivityRecord.completeResumeLocked()
- ActivityStackSuperVisor.scheduleIdleTimeoutLocked()
- IDLE_TIMEOUT 的值是 10
- ActivityStackSupervisorHandler. activityIdleInternalLocked()处理的如果 10s 内主线程执行了 Idler 的话,就会移除这个消息
小结:执行finish流程中 当前获取焦点的恢复要显示的 activity 会标记10s的超时,如果10s没执行Idler就会强制执行。