当前位置:网站首页>细谈APP开发焦点问题:AMS 系统时间调节原理
细谈APP开发焦点问题:AMS 系统时间调节原理
2022-08-10 22:54:00 【Android技术栈】
前言
AMS提供的主要功能:
- 统一调度各个应用程序的Activity
应用程序需要启动Activity–>报告给AMS,决定是否可以启动–>如果可以,通知应用程序运行指定Activity
AMS必须知道各个应用程序运行的Activity
- 内存管理
Activity退出时不会立即被杀死,只有在内存紧张时才会自动被杀,这些操作由AMS管理
- 进程管理
AMS向外提供了查询系统正在运行的进程信息的API
一、AMS启动
1.启动流程
AMS在SystemServer进程initAndLoop()函数中被启动并且初始化,进过以下步骤:
AMS.main()函数,创建AMS实例,并且创建Android运行环境得到一个ActivityThread和一个Context
AMS.setSystemProcess()函数,注册AMS服务到ServiceManager中。并且为system_server进程创建ProcessRecord,将该进程纳入管理中
AMS.installSystemProvider()函数,为system_server进程加载SettingsProvider。
AMS.systemReady()函数,做系统启动完毕后的工作,呈现HomeActivity。
2.AMS重要数据结构
AMS定义了几个数据类用于Process、Activity、Task信息
2.1 进程数据类ProcessRecord
用于记录一个进程相关信息
2.2保存Activity信息数据类ActivityRecord
用于保存一个Activity的信息
在ActivityRecord内部提供Token类实现IApplicationToken.Stub可以实现IPC回调其方法。一般是在WMS内部对其IPC调用
2.3任务栈信息数据类TaskRecord
记录Activity所属任务栈信息。
二、Activity调度机制
Activity调度过程:
应用进程启动或者停止Activity—>报告给AMS,其内部维护所有应用进程启动或者停止Activity的记录—>AMS更新内部记录,并通知客户端进程操作—>客户端进程接收通知,执行操作
启动Activity的各种方式:
应用程序中调用startActivity()
在Home程序中单击应用程序图标启动Activity
按“back”停止当前Activity启动新Activity
长按“home”显示当前任务列表选择一个启动
1.ActivityThread类关系
AMS通过Binder跨进程通知ActivityThread启动、停止指定Activity
ActivityThread作为Binder服务端实现指定接口由AMS远程调用
ActivityThread可以看做是进程的Android运行环境
2.Activity的launchMode
standard:默认启动模式,不管有没有已存在的实例都生成新的实例
singleTop:如果栈顶存在对应的实例则重复利用不生产新的实例,不存在则新建实例
singleTask:如果栈内存在对于的实例则使此Activity实例之上的其他Activity实例都出栈,使此Activity实例成为栈顶对象显示
singleInstance:启用一个新栈放入新建Activity实例,并且该栈内只允许存在这一个Activity实例
Intent中涉及到的Activity启动方式常量:
FLAG_ACTIVITY_NEW_TASK:将目标Activity放置到新的task中。
FLAG_ACTIVITY_CLEAR_TASK:启动一个Activity时先清除和其有关联的task,并新建Activity实例将其放入新的task中。必须和上面变量一起使用
FLAG_ACTIVITY_CLEAR_TOP:启动一个不处于栈顶的Activity时,清除排在它前面的Activity使其显示出来。
3.AMS启动Activity流程
调用步骤过程如下:
1.首先IPC调用AMS方法传入参数启动指定Activity
2.在AMS中首先查询PKMS获取该ActivityInfo,新建ActivityRecord和根据lunchMod创建TaskRecord两个重要变量,并且将ActivityRecord添加到task栈顶作为准备启动的Activity
3.在正式启动Activity之前首先检查其进程是否启动,为启动时通知AMS启动对应进程
AMS创建Activity对应进程及启动Activity的整个调用步骤过程如下:
1.首先就是zygote进程fork新进程,指定新进程执行需要启动的ActivityThread类
2.在ActivityThread的main()方法中:
首先新建ActivityThread对象
接着回调AMS接口通知其应用进程已启动成功
最后开启主线程消息循环,处理消息
3.其中上步骤第二点在与AMS交互中IPC调用AMS的attachApplication()函数中:
首先根据pid查找对应的ProcessRecord
设置该应用退出时的回调接口
修改ProcessRecord一些参数
最后与应用进程交互,开始创建Application对象
4.AMS与应用进程交互时会发出一个异步消息,该消息内部:
配置运行时信息
安装该Application对应的ContentProvider
生成一个Application对象并且回调onCreate()函数
5.AMS与应用进程交互完接着准备启动目标Activity,在ActivityStackSupervisor.attachApplicationLocked()函数中会首先获取需要启动的ActivityRecord并保存到对应的ProcessRecord,接着IPC调用应用进程启动Activity
6.在应用进程中也是异步消息处理
首先反射实例化目标Activity对象,回调相应onStart()之前的生命周期函数
接着回调onResume()函数并且添加一个Idler消息对象到队列中。该对象内部方法会调用到AMS中的相应方法处理因此次启动而被暂停的Activity的相关声明周期函数处理
7.同时在AMS中会将task添加到最近任务列表中,并且发送10s定时等待这个Activity处理结果
8.此时目标Activity已经被成功启动,接着会处理一些Pending组件,这些组件可能是在系统启动未成功时发起的一些启动指令
最终一个Activity启动成功
更多Android前言技术进阶;我自荐一套 《完整的Android的资料,以及一些视频课讲解》
有需要的朋友可以在评论区下方留言发送 “进阶” 或 “笔记” 或者直接私信我 即可免费获取
最后我想说:
对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们
技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面
Android 架构师之路还很漫长,与君共勉
边栏推荐
- 解析方法的参数列表(包含参数名称)
- 开源一夏 | 盘点那些 Golang 标星超过 20 K 的优质项目
- RecyclerView设置缓存大小
- Leave a message with a prize | OpenBMB x Tsinghua University NLP: The update of the large model open class is complete!
- ASCII, Unicode and UTF-8
- 二叉树 | 代码随想录学习笔记
- 高学历毕业生,该学单片机还是plc?
- Glide缓存核心原理详解
- JS学习 2022080
- 【uniapp】uniapp微信小程序开发:启动微信开发者工具提示no such file or directory错误
猜你喜欢
房间虚拟样板间vr制作及价格
Pro-test is effective | A method to deal with missing features of risk control data
Glide监听Activity生命周期源码分析
生态伙伴开发实践 | 智慧检测实验室应用系统快速接入指令集数字底座
一、ICESat-2数据查询,下载,与处理
Android | 安卓好用软件来袭,多御安全浏览器免费又强大
国内vr虚拟全景技术领先的公司
RK3399 platform development series explanation (kernel-driven peripherals) 6.35, IAM20680 gyroscope introduction
"DevOps Night Talk" - Pilot - Introduction to CNCF Open Source DevOps Project DevStream - feat. PMC member Hu Tao
DC-9靶场下载及渗透实战详细过程(DC靶场系列)
随机推荐
HGAME 2022 Final Pokemon v2 writeup
诺诚健华通过注册:施一公家族身价15亿 高瓴浮亏5亿港元
Merge k sorted linked lists
[MySQL] Using join buffer (Block Nested Loop) in left join due to character set in mysql
如何利用fiddler连接手机抓包APP
常用代码扩展点设计方式
RK3399 platform development series explanation (kernel-driven peripherals) 6.35, IAM20680 gyroscope introduction
二叉树 | 代码随想录学习笔记
高学历毕业生,该学单片机还是plc?
基于深度学习的三维点云分割综述
ITK 读取一个目录中的一个序列,然后改变头信息,将多张dcm图像写成一个dcm文件。
Redis
Three major logs in mysql
MySQL:MySQL的集群——主从复制的原理和配置
ArcGIS应用基础知识
Btree索引和Hash索引
CIKM2022 | 基于双向Transformers对比学习的序列推荐
KRONES克朗斯电源维修0-901-17-350-8技术概论
二叉树 | 层序遍历 | leecode刷题笔记
信息系统项目管理师核心考点(六十五)信息安全基础知识网络安全