再谈启动一个Activity大致时序图

太多了,笔者不想写,

读者可通过PlantUML插件查看如下PUML文件生成的时序图。

补充说明下,Android31版本。

@startuml
'https://plantuml.com/sequence-diagram
skinparam dpi 800
scale 15000 width
scale 5000 heightautonumber
==Launcher==
Launcher -> Activity:startActivity(intent)
Activity->Activity:startActivity(intent,bundle)
Activity->Activity:startActivityForResult
Activity->Instrumentation:execStartActivity
note left
activity通过调用内部成员
mInstrumentation与atms
交互,即将开始进入系统进程
end note
Instrumentation->ActivityTaskManagerService.Stub:startActivity
==SystemService==
ActivityTaskManagerService.Stub->ActivityTaskManagerService:StartActivity
ActivityTaskManagerService->ActivityTaskManagerService:startActivityAsUser
ActivityTaskManagerService->ActivityTaskManagerService:startActivityAsUser
ActivityTaskManagerService->ActivityStarter:execute
ActivityStarter->ActivityStarter:executeRequest
note left
这里,会验证启动参数的合法性,
随后,创建一个ActivityRecord
作为一个Activity的唯一存在标识
end note
ActivityStarter->ActivityStarter:startActivityUnchecked
ActivityStarter->ActivityStarter:startActivityInner
note left
此函数的功能,如果没有Stack,就要新创建一个Stack,
也就是ActivityStack,保存到mTargetTask中,
通过setNewTask将待启动的ActivityRecord
和新创建的Stack绑定,并且将其置于Stack Top,
see ActivityStack::startActivityLocked()
see ActivityStack::moveToFront()
end note
ActivityStarter->ActivityStack:startActivityLocked
note left
这就是绑定ActivityRecord和新创建的Stack(Task)
end noteActivityStack->RootWindowContainer:resumeFocusedStacksTopActivities
note left
对于新启动的Activity,走此分支
end noteRootWindowContainer->ActivityStack:resumeTopActivityUncheckedLocked
note left
此ActivityStack是13步新创建的,
开始调度Activity
end noteActivityStack->ActivityStack:resumeTopActivityInnerLockednote left
这一步很关键,因为要Resume即将启动的Activity,
那么,首先要检查即将启动的Activity在没在栈顶,
如果不在,就要去pause栈顶的Activity
end note
ActivityStack->TaskDisplayArea:pauseBackStacks
note left
这里返回是否在pause栈顶的Activity,
一般这里会返回true,因为需要pause Launcher,
传入next参数即topRunningActivity
end notenote right
逻辑是去topStack中去判断是否有可见Activity,
如果有则pause掉,否则返回false,
end note
TaskDisplayArea->ActivityStack:startPausingLocked
note right
开始pause Launcher,
通过mAtmService(ATMS)获取生命周期管理,
执行生命周期PauseActivityItem事务
end note
ActivityStack->ClientLifecycleManager:scheduleTransactionnote left
注意,这里传的参数有PauseActivityItem
end note
ClientLifecycleManager->ClientLifecycleManager:scheduleTransaction
ClientLifecycleManager->ClientTransaction:schedule
ClientTransaction->IApplicationThread:scheduleTransaction
note right
进入Launcher进程,去执行Pause事务
end noteTaskDisplayArea-->ActivityStack:pauseBackStacks:true
ActivityStack-->RootWindowContainer:resumeTopActivityInnerLocked:true
RootWindowContainer-->ActivityStarter:resumeTopActivityUncheckedLocked:true
ActivityStarter-->ActivityStarter:ActivityStarter:START_SUCCESS==Launcher进程==
IApplicationThread->ActivityThread:scheduleTransaction
ActivityThread->ActivityThread:sendMessage(159,transaction)
ActivityThread->Handler:sendMessage
note right
这里159代表事务EXECUTE_TRANSACTION
一顿Looper后可以直接看handleMessage处
end noteHandler->Handler:handleMessage
ActivityThread->TransactionExecutor:executeTransactionExecutor->TransactionExecutor:executeLifecycleState
TransactionExecutor->PauseActivityItem:execute
PauseActivityItem->ActivityThread:handlePauseActivity
note right
熟悉的ActivityThread,开始pause Activity
end noteActivityThread->ActivityThread:performPauseActivity
ActivityThread->ActivityThread:performPauseActivityIfNeeded
ActivityThread->Instrumentation:callActivityOnPause
Instrumentation->Activity:performPause
Activity->Activity:onPauseTransactionExecutor->PauseActivityItem:postExecute
PauseActivityItem->ActivityTaskManagerService.Stub:activityPaused
note left
通知系统进程,Launcher已经pause
end note
==SystemService==
ActivityTaskManagerService->ActivityRecord:activityPaused(false/*timeout*/)
note right
拓展:这里就是其中一种ANR,如果没超时就移除anr回调,
end note
ActivityRecord->ActivityStack:completePauseLocked(true/*resumeNext*/,null)
ActivityStack->RootWindowContainer:resumeFocusedStacksTopActivitiesRootWindowContainer->ActivityStack:resumeTopActivityUncheckedLockednote right
找到下一个即将启动的ActivityStack,开始Resume
end noteActivityStack->ActivityStack:resumeTopActivityInnerLockedActivityStack->TaskDisplayArea:pauseBackStacks
TaskDisplayArea-->ActivityStack:pauseBackStacks:falseActivityStack->ActivityStackSupervisor:startSpecificActivity
note right
这里通过ActivityRecord去获取WindowProcessController,
这个和进程相关,第一次启动肯定没有对应进程,那么就需要创建进程
end noteActivityStackSupervisor->ActivityTaskManagerService:startProcessAsync
ActivityTaskManagerService->ActivityManagerInternal:startProcess
note right
这里通过handler调用到此处,
ActivityManagerInternal是一个抽象类,
其此处实例是ActivityServiceManager的LocalService
end note
ActivityManagerInternal->ActivityManagerService:startProcessLocked
ActivityManagerService->ProcessList:startProcessLocked
ProcessList->ProcessList:startProcessLocked
ProcessList->ProcessList:startProcessLocked
ProcessList->ProcessList:startProcessLocked
ProcessList->ProcessList:startProcess
ProcessList->Process:start
Process->ZygoteProcess:start
ZygoteProcess->ZygoteProcess:startViaZygote
note right
写入参数,通过socket发送给Zygote
end note
ZygoteProcess->ZygoteProcess:zygoteSendArgsAndGetResult
ZygoteProcess->ZygoteProcess:attemptZygoteSendArgsAndGetResult
ZygoteProcess->ZygoteState:write
note right
正式发送给zygote
end note
ZygoteProcess->ZygoteState:read
note right
主动读取结果,获取新启动的进程pid,保存到上下文中,
等待attach新启动的进程,由此,我们进入Zygote进程
end note==Zygote==
ZygoteInit->ZygoteInit:main
ZygoteInit->ZygoteServer:runSelectLoop
ZygoteServer->ZygoteConnection:processOneCommand
ZygoteConnection->Zygote:forkAndSpecialize
note right
这个返回值很关键,如果在此处将fork出两个进程,
如果是新创建的进程,pid为0,否则就是Zygote进程
end noteZygote-->ZygoteConnection:pid
ZygoteConnection->ZygoteConnection:handleParentProc
ZygoteConnection->ZygoteState:write
note right
写入新创建的pid给SystemService
end note
ZygoteConnection-->ZygoteServer:processOneCommand:Runnable
ZygoteServer->ZygoteServer:runSelectLoop
note right
继续监听其它连接,完毕
end note
==App进程==
Zygote-->ZygoteConnection:pid
ZygoteConnection->ZygoteConnection:handleChildProc
ZygoteConnection->closeSocket
ZygoteConnection->ZygoteInit:childZygoteInit
ZygoteInit->RuntimeInit:findStaticMain
note right
这里找到ActivityThread.main()方法
end note
RuntimeInit-->ZygoteInit:main
RuntimeInit-->ZygoteConnection:main
ZygoteConnection-->ZygoteServer:main
ZygoteServer-->ZygoteInit:runSelectLoop:main
ZygoteInit->ActivityThread:main
note left
至此,app的入口正式启动,
这里负责创建Looper.prepare();
还有最重要的attach,毕竟刚创建的app是个新生儿,
需要把自己注册到android世界中,才能获得活动的权利
最后进入主线程死循环loop
end note
ActivityThread->ActivityThread:attach
ActivityThread->ActivityManagerService.Stub:attachApplication
==SystemService==
ActivityManagerService.Stub->ActivityManagerService:attachApplication
ActivityManagerService->ActivityManagerService:attachApplicationLocked
ActivityManagerService->ActivityTaskManagerInternal
note right
这个是ATMS的LocalService
end note
ActivityTaskManagerInternal->RootWindowContainer:attachApplication
RootWindowContainer->RootWindowContainer:startActivityForAttachedApplicationIfNeeded
RootWindowContainer->ActivityStackSupervisor:realStartActivityLocked
note left
现在进程有了,该真正启动了
end note
ActivityStackSupervisor->ClientLifecycleManager:scheduleTransaction
note right
这里面约莫842行,给事务添加了回调,LaunchActivityItem;
然后也设置的生命周期状态ResumeActivityItem
end note
ClientLifecycleManager->ClientTransaction:schedule
ClientTransaction->IApplicationThread:scheduleTransaction
==App进程==
IApplicationThread->ActivityThread:scheduleTransaction
ActivityThread->ActivityThread:sendMessage(159,transaction)
ActivityThread->Handler:sendMessage
Handler->TransactionExecutor:execute
TransactionExecutor->TransactionExecutor:executeCallbacks
note right
注意此处的LaunchActivityItem
end note
TransactionExecutor->LaunchActivityItem:execute
LaunchActivityItem->ActivityThread:handleLaunchActivity
ActivityThread->ActivityThread:performLaunchActivity
ActivityThread->Instrumentation:newActivity
Instrumentation-->ActivityThread:activity
ActivityThread->Activity:attachnote left
那么,activity就被反射创建了,
这里,创建了PhoneWindow等必要成员
end note
ActivityThread->Instrumentation:callActivityOnCreate
Instrumentation->Activity:performCreate
Activity->Activity:onCreate
Activity-->TransactionExecutor
TransactionExecutor->TransactionExecutor:executeLifecycleState
TransactionExecutor->TransactionExecutor:cycleToPath
note left
这样终态传入的是Resume,因此需要在此处拿到IntArray的生命周期表
end note
TransactionExecutor->TransactionExecutor:performLifecycleSequence
note left
挨个走start、resume,
end note
TransactionExecutor->ActivityThread:handleStartActivity
ActivityThread->Activity:performStart
Activity->Instrumentation:callActivityOnStart
Instrumentation->Activity:onStart
Activity-->TransactionExecutorTransactionExecutor->ActivityThread:handleResumeActivity
ActivityThread->Activity:performResume
Activity->Instrumentation:callActivityOnResume
Instrumentation->Activity:onResume
Activity-->ActivityThread:handleResumeActivity
note left
此处,继续走handlerResumeActivity接下来的分支,
就是绑定Activity和Window的过程,
wm.addView(decor, l);
自此就是View绘制流程(极多的另一流程),然后显示在屏幕上
end noteActivity-->ActivityThread:main
ActivityThread->Looper:loop
@enduml

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/439504.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SeaTunnel Web安装 一把成

安装相关jar包,以及SeaTunnel 和Web 打成的包,可以直接使用,但是需要安装MySQL客户端的分享: 链接:https://pan.baidu.com/s/1qrt1RAX38SgIpNklbQJ7pA 提取码:0kmf 1. 环境准备 环境名称版本系统环境C…

echarts:获取省、市、区/县、镇的地图数据

目录 第一章 前言 第二章 获取地图的数据(GeoJSON格式) 2.1 获取省、市、区/县地图数据 2.2 获取乡/镇/街道地图数据 第一章 前言 需求:接到要做大屏的需求,其中需要用echarts绘画一个地图,但是需要的地图是区/县…

隐马尔可夫模型系列——(五)实际应用

一、语音识别 隐马尔可夫模型(Hidden Markov Model,HMM)在语音识别中被广泛应用,它是一种统计模型,用于建模序列数据的动态过程。语音识别任务涉及将声音信号转化为文本或命令,而HMM可以帮助我们解决这个问…

AI工具【OCR 01】Java可使用的OCR工具Tess4J使用举例(身份证信息识别核心代码及信息提前方法分享)

Java可使用的OCR工具Tess4J使用举例 1.简介1.1 简单介绍1.2 官方说明 2.使用举例2.1 依赖及语言数据包2.2 核心代码2.3 识别身份证信息2.3.1 核心代码2.3.2 截取指定字符2.3.3 去掉字符串里的非中文字符2.3.4 提取出生日期(待优化)2.3.5 实测 3.总结 1.简…

UE5.1_常用节点说明(经常忘记怎么用?)(常改)

UE5.1_常用节点说明(经常忘记怎么用?)(常改) 1. Gate——门节点。只有当门是Open状态才会执行Exit后面的代码。 Open开门;Close关门;Toggle开门和关门交替。 2. 关于控制ArmLength即控制相机前…

行测-数量关系:2. 工程问题、经济利润问题

1、工程问题 1.1 给具体单位型 A,二元一次方程 1.2 给完工时间型 18 D D,注意问题是共需要多少天。 A,代入法是最快的。 A C 1.3 给效率比例型 C,注意是问的共需要多少天。 A C A 2、经济利润问题 2.1 基础经济★★★ B B&#xf…

MySQL安全(一)权限系统

一、授权 1、创建用户 在MySQL中,管理员可以通过以下命令创建用户: namelocalhost IDENTIFIED BY password; name是要创建的用户名,localhost表示该用户只能从本地连接到MySQL,password是该用户的密码。如果要允许该用户从任何…

22.云原生之GitLab CICD实战及解析【干货】

云原生专栏大纲 文章目录 准备工作gitlab-ci.yml流水线mven打包项目制作并推送镜像kaniko方式docker方式 部署到k8s验证执行情况 GitLab Runner k8s执行器工作流程注册配置kubernetes runnerkubernetes runner配置通过修改 Pod 规范为每个构建作业创建一个 PVC自定义卷装载持久…

利用外卖系统源码构建高效的在线订餐平台

在当今数字化时代,外卖服务已成为人们日常生活中不可或缺的一部分。为了满足用户需求,许多创业者和企业都希望搭建自己的在线订餐平台。利用现有的外卖系统源码,可以快速构建一个高效、安全的在线订餐平台。本文将介绍如何利用外卖系统源码来…

方案:将vue项目放在SpringMVC中,并用tomcat访问

需要先将项目生成一次war包才能访问项目的webapp文件夹下的资源,否则tomcat的webapp文件夹下面不会生成对应资源文件夹就无法访问。 问题:目录如下: 今天我测试了一下将vue打包后,放入webapp下面访问,却发现vue项目无…

C# 使用WMI监听进程的启动和关闭

写在前面 Windows Management Instrumentation(WMI)是用于管理基于 Windows 操作系统的数据和操作的基础结构。具体的API可以查看 WMI编程手册。 WMIC 是WMI的命令行管理工具,使用 WMIC,不但可以管理本地计算机,还可…

Walrus 0.5发布:重构交互流程,打造开箱即用的部署体验

开源应用管理平台 Walrus 0.5 已于近日正式发布! Walrus 0.4 引入了全新应用模型,极大程度减少了重复的配置工作,并为研发团队屏蔽了云原生及基础设施的复杂度。Walrus 0.5 在这一基础上,通过重构交互流程、增强抽象能力&#xff…