IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android源码分析:finish startActivity -> 正文阅读

[移动开发]Android源码分析:finish startActivity

准备知识:

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()和回调

  1. Activity.finish(DONT_FINISH_TASK_WITH_ACTIVITY);
    1. 搭载了带参数的 finish() 方法。参数是 DONT_FINISH_TASK_WITH_ACTIVITY ,含义也很直白,不会销毁 Activity 所在的任务栈。
    2. 其中activity中利用 Binder 调用了 AMS.finishActivity() 方法
  2. ActivityManagerService.finishActivity(IBinder token, int resultCode, Intent resultData,int finishTask)
    1. ActivityStack.requestFinishActivityLocked()
  3. ActivityStack.requestFinishActivityLocked()
  4. ActivityStack.finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,String reason, boolean oomAdj, boolean pauseImmediately)
    1. r.makeFinishingLocked();// 前面会做重复 finish 的检测就是依赖这个值
    2. startPausingLocked(false, false, null, pauseImmediately);// 开始 pause mResumedActivity
  5. ActivityStack.startPausingLocked(boolean userLeaving, boolean uiSleeping,ActivityRecord resuming, boolean pauseImmediately)
    1. 第一步通过 ClientLifecycleManager 分发生命周期流程。
    2. 第二步是发送一个延时 500ms 的消息,等待一下 onPause 流程.但是如果第一步中在 500ms 内已经完成了流程,则会取消这个消息。所以这两步的最终逻辑其实是一致的。这里就直接看第一步。
  6. ClientLifecycleManager它会向主线程的 Handler H 发送 EXECUTE_TRANSACTION 事件,调用 XXXActivityItem 的 execute() 和 postExecute() 方法。execute() 方法中会 Binder 调用 ActivityThread 中对应的 handleXXXActivity() 方法。在这里就是 handlePauseActivity() 方法,其中会通过 Instrumentation.callActivityOnPause(r.activity) 方法回调 Activity.onPause() 。
  7. Instrumentation.callActivityOnPause(Activity activity)
    1. activity.performPause();Activity onPause()被执行。
    2. onPause() 方法就被执行了。但是流程没有结束,接着就该显示下一个 Activity 了。

小结:调用finish会立即执行当前Activity的onPause和下一个Activity的显示流程

1.2 执行finish()流程

  1. 前面刚刚说过会调用 PauseActivityItem 的 execute() 和 postExecute() 方法。execute() 方法回调了当前 Activity.onPause(),而 postExecute() 方法就是去寻找要显示的 Activity 。
  2. PauseActivityItem.postExecute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions)
    1. ActivityManager.getService().activityPaused(token);
  3. ActivityManagerService.activityPaused(IBinder token)
  4. ActivityStack.activityPausedLocked()
    1. mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r) ,移除的就是之前延迟 500ms 的消息。接着看 completePauseLocked() 方法。
  5. ActivityStack.ompletePauseLocked(boolean resumeNext, ActivityRecord resuming)
    1. 判断了 finishing 状态,还记得 finishing 在何处被赋值为 true 的吗?在 Activity.finish() -> AMS.finishActivity() -> ActivitySta
    2. ck.requestFinishActivityLocked() -> ActivityStack.finishActivityLocked() 方法中。所以接着调用的是 finishCurrentActivityLocked() 方法
    3. // 当前获取焦点的 mStackSupervisor.getFocusedStack(); // 恢复要显示的 activity mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null); 此时会标记10s的超时
  6. ActivityStack.finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj,String reason)
    1. mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)&& next != null && !next.nowVisible addToStopping
    2. mode == FINISH_IMMEDIATELY || (prevState == PAUSED && (mode == FINISH_AFTER_PAUSE || inPinnedWindowingMode()))|| finishingActivityInNonFocusedStack|| prevState == STOPPING|| prevState == STOPPED|| prevState == ActivityState.INITIALIZING
  7. ActivityStack.addToStopping
    1. 这些在等待销毁的 Activity 被保存在了 ActivityStackSupervisor 的 mStoppingActivities 集合中,它是一个 ArrayList 。
    2. 整个 finish 流程就到此为止了。前一个 Activity 被保存在了 ActivityStackSupervisor.mStoppingActivities 集合中,新的 Activity 被显示出来了。

小结:finish流程执行完成只是将该Activity放入待销毁的ArrayList 中

1.3 真正回调onStop,onDestroy

  1. ActivityThread.handleResumeActivity()
    1. handleResumeActivity() 方法是整个 UI 显示流程的重中之重,它首先会回调 Activity.onResume() , 然后将 DecorView 添加到 Window 上,其中又包括了创建 ViewRootImpl,创建 Choreographer,与 WMS 进行 Binder 通信,注册 vsync 信号,著名的 measure/draw/layout
    2. 完成最终的界面绘制和显示之后Looper.myQueue().addIdleHandler(new Idler())
  2. MessageQueue.next()
    1. 当新的 Activity 完成页面绘制并显示之后,主线程就可以停下歇一歇,来执行 IdleHandler 了。再回来 handleResumeActivity() 中来
  3. ActivityThread.handleResumeActivity()
    1. Idler implements MessageQueue.IdleHandler
      1. Idler. queueIdle()
        1. 调用 AMS.activityIdle()
  4. ActivityManagerService.activityIdle(IBinder token, Configuration config, boolean stopProfiling)
  5. ActivityStackSupervisor.activityIdleInternalLocked()
    1. stops 和 finishes 分别是要 stop 和 destroy 的两个 ActivityRecord 数组。stops 数组是通过 ActivityStackSuperVisor.processStoppingActivitiesLocked() 方法获取的
  6. ActivityStackSupervisor.processStoppingActivitiesLocked(ActivityRecord idleActivity, boolean remove, boolean processPausingActivities)
    1. 遍历的是ActivityStackSuperVisor 中的 mStoppingActivities 集合 。在前面分析 finish() 流程到最后的 addToStopping() 方法时提到过,

小结:MessageQueue.next() 中主线程完成后执行IdleHandler,去执行ArrayList中待销毁的Activity

1.4 为什么10s onStop/onDestroy:

  1. ActivityStackSuperVisor.resumeFocusedStackTopActivityLocked()
  2. ActivityStack.resumeTopActivityUncheckedLocked()
  3. ActivityStack.resumeTopActivityInnerLocked()
  4. ActivityRecord.completeResumeLocked()
  5. ActivityStackSuperVisor.scheduleIdleTimeoutLocked()
    1. IDLE_TIMEOUT 的值是 10
  6. ActivityStackSupervisorHandler. activityIdleInternalLocked()处理的如果 10s 内主线程执行了 Idler 的话,就会移除这个消息

小结:执行finish流程中 当前获取焦点的恢复要显示的 activity 会标记10s的超时,如果10s没执行Idler就会强制执行。

参考

  1. 为什么 Activity.finish() 之后 10s 才 onDestroy ?
  2. ActivityManagerService 你了解多少?
  3. (Android 9.0)Activity启动流程源码分析
  4. IdleHandler 的原理分析和妙用
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-12 16:42:49  更:2021-08-12 16:44:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 23:33:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码