拒绝摆烂,Android AMS应该打卡学习的n件事
创始人
2025-05-29 05:54:37
0

AMS(ActivityManagerService)介绍

从java角度来看,ams就是一个java对象,实现了Ibinder接口,所以它是一个用于进程之间通信的接口,这个对象初始化是在systemServer.java 的run()方法里面

public Lifecycle(Context context) { super(context); mService = new ActivityManagerService(context);}

AMS是什么?

  1. 从java角度来看,ams就是一个java对象,实现了Ibinder接口,所以它是一个用于进程之间通信的 接口,这个对象初始化是在systemServer.java 的run()方法里面
  2. AMS是一个服务 ActivityManagerService从名字就可以看出,它是一个服务,用来管理Activity,而且是一个系统服务, 就是包管理服务,电池管理服务,震动管理服务等。
  3. AMS是一个Binder ams实现了Ibinder接口,所以它是一个Binder,这意味着他不但可以用于进程间通信,还是一个线程,因为一个Binder就是一个线程。

启动流程

  • Init 初始化Linux 层,处理部分服务
  • 挂载和创建系统文件
  • 解析rc文件:
  • rc 文件中有很多action
  • 进入无限循环
  1. 执行action:zygote 进程就在这里启动
  • for循环去解析参数,根据rc 文件中的action 执行相应操作
  1. 检测并重启需要的进程
  2. 接收子进程的SIGCHLD信号,执行响应的方法
  • 防止子进程成为僵尸进程
  • zygote 层:
  • native 部分:
  • 初始化android 运行时环境(ART),因为Java 代码需要运行在虚拟机中;
  • 初始化 JNI ,因为native 层与 Java 层需要通信
  • 执行ZygoteInit.main 方法,进入Java 部分
  • Java 部分:
  • 创建 socket:实现通信
  • 执行预加载:加快进程的启动速度
  • 通过fork 创建 SystemServer 进程
  • 进入循环:等待AMS 的通知,并根据通知创建对应的进程

引申问题:

  • zygote 中的Java 层是如何创建出SystemServer 的?
  • SystemServer 是怎么启动的?

本文正文内容

SystemServer 进程的创建时机

  • 一句话描述:
  • Zygote 进程通过forkSystemServer类 调用fork(),创建其子进程;这个子进程就是SystemServer 进程
  • 业务逻辑:

SystemServer 进程的创建过程

  • 前情提要:
  • 从ZygoteInit.java 中的main 方法。进入forkSystemServer类;此时,属于Zygote 进程
  • 进程实际上是没有native,java之分的;我们常说Zygote 进程在native 层,SystemServer 进程在Java 层,这可看做一种约定。
  • 第一步:参数赋值
  • 通过字符串数组args 进行赋值:包含uid,gid,nice-name(进程名)
  • 第二步:创建子进程,拿到pid
  • 通过Zygote.forkSystemServer 调用fork(),创建子进程并返回pid

怎样理解Zygote 进程与SystemServer 进程的关系?

  • 一句话描述:
  • Zygote 进程是SystemServer 进程的父进程,两进程共用一段代码;
  • 怎么理解进程号(pid) ?
  • pid 代表每个进程的进程号。但是,当pid 接收返回值时,其表示子进程的进程号。
  • pid的值:进程的唯一标识符
  • 子进程是父进程fork 出来的,可以看作是拷贝。通过pid 的值区分父子进程
  • 定义子进程处理逻辑
  • if(pid == 0){ 业务代码 }
  • 子进程的pid 比父进程的pid 大,是递增的
  • pid 的值可以看成是随机的,但是也不能这样说。
  • 举个例子:
  • 假如Zygote 的进程号为1000,SystemServer 的进程号是6000。那么,Zygote 中的pid 的返回值就是6000,也就是Zygote fork 出的子进程的进程号。而SystemServer 中的pid 的返回值为0,因为它没有子进程;

怎么通过代码区别父子进程?

  • 前情提要:
  • 父子进程共用一段代码,这段代码在父子进程中各执行一次;
  • 业务需求:
  • 在共用代码中,让某段代码仅在子进程中执行
javaif(pid == 0){//子进程域//子进程执行逻辑}
Copy

SystemServer 进程的执行时机:

  • 基本环境:
  • 上文中我们知道了SystemServer 进程是Zygote 进程通过forkSystemServer 调用fork() 函数后创建出来的。那么SystemServer 进程具体执行时,应当调用SystemServer.main();
  • 调用时机:通过下列代码调用至forkSystemServer
  • 执行条件:if(pid == 0)
  • 在SystemServer进程中
java//forkSystemServer return handleSystemServerProcess(parsedArags);

Copy

源码阅读细节:有个方法是搜不到的

  • 问题描述:
  • 在forkSystemServer 类中想查看nativeForkSystemServer() 的执行细节。
  • 正常情况下,对于系统层函数在AndroidRuntime.cpp 中直接搜方法名就可以搜到具体的函数。但是,这对于nativeForkSystemServer() 是不行的。
  • 解决手段:在AndroidRuntime.cpp搜com_android_internal_os_Zygote
  • 找到这句代码并点击进入
    extern int register_com_android_internal_os_Zygote(JNIEnv *env);
Copy
  • 在这个函数返回值处,进入gMethods[];native 函数都在这里。
  • 为什么会出现这种问题?
  • 这是JNI 层代码的命名规范,但是这个函数在当初代码编写的时候,违背了主流规范才导致我们直接搜是搜不到的。
  • JNI 层代码的命名规范:包名 具体的函数名

SystemServer 进程的执行过程:

  • 前情提要:
  • 业务需求:需要启动SystemServer.main()
  • 代码入口:进入SystemServer 进程
    javaif(pid == 0){//此时在SystemServer 进程中…………return handleSystemServerProcess(parsedArgs);    }
Copy
  • handleSystemServerProcess() 通过反射启动SystemServer.main()
  • 源码依据:
  • 先是拿到了ClassLoader,接着调用了ZygoteInit.zygoteInit();

zygoteInit() 干了什么?

  • 启动Binder 线程池:
  • ZygoteInit.nativeZygoteInit();
  • 运行SystemServer.main()
  • RuntimeInit.applicationInit();

Binder 线程池是如何启动的?

  • 前情提要:
  • 源码入口:nativeZygoteInit()
  • 对应的JNI 层代码
javacom_android_internal_os_ZygoteInit_nativeZygoteInit()
Copy
  • 重要代码解析:
  • 代码展示:
javagCurRuntime->onZygoteInit();
Copy
  • gCurRuntime 是什么?
  • 指AppRuntime,且AppRuntime 继承自AndroidRuntime;
  • 因为SystemServer 是Zygote 的子进程;
  • 由于代码共享,所以Zygote 有AndroidRuntime,那SystemServer 也有;并且,在Zygote 初始化的时候,会将AndroidRuntime 一同初始化。SystemServer 相当于继承了AndroidRuntime,因此具备安卓运行时环境;
  • onZygoteInit():在这里就启动了Binder 线程池
  • 代码展示:app_main.cpp
javavirtual void onZygoteInit(){sp proc = ProcessState::self();ALOGV("App process: Starting thread poll.\n");proc->startThreadPool();}
Copy
  • 经验总结:每个进程都是有Binder 机制的,因为SystemServer 进程执行时会开启Binder 线程池。

SystemServer.main() 执行过程

  • 一句话描述:通过反射执行,在封装类中调用。
  • 前情提要:
  • 源码入口:RuntimeInit.applicationInit();
  • 核心代码:findStaticMain();
  • 通过反射执行SystemServer.main()
  • 拿到类:classname 就是SystemServer
javacl = Class.forName(classname,true,classLoader);
Copy
  • 拿到方法:SystemServer.main()
m = cl.getMethod("main", new Class[] { String[].class });
Copy
  • 先进行封装:
return new MethodAndArgsCaller(m, argv);Copy
  • 在封装类中,调用代码:
javastatic class MethodAndArgsCaller implements Runnable {//开启子线程执行public void run() {try {// 通过反射真正执行 SystemServer.main() mMethod.invoke(null, new Object[] { mArgs });}}Copy
  • 这个run() 是什么时候执行的?
  • ZygoteInit.java中main执行的,forkSystemServer之后会返回一个r;这个r 就是MethodAndArgsCaller 这个封装类;
  • 代码展示:
javaif(startSystemServer){Runnable r = forkSystemServer(xxxxx);if(r != null){//如果是Zygote 进程,r 才为空;r.run();return;}}Copy

SystemServer().run() 干了什么?

  • 一句话描述:SystemServer 通过标记,完成不同阶段的任务。总体来说,干了三件事。创建系统上下文,创建服务管理者,创建三类服务
  • 设置标记方法:
    mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);Copy
  • 业务流程图:

  • 前情提要:
  • 此时,我们分析的是SystemServer 进程的main() 方法;但,实际上调用的是SystemServer().run();
    public static void main(String[] args) {//SystemServer.main()new SystemServer().run();}Copy
  • 创建系统上下文:
  createSystemContext();

Copy

  • 创建系统服务管理者:
  mSystemServiceManager = new SystemServiceManager(mSystemContext);

Copy

  • 创建三类服务:
  • 引导服务:AMS
    //引导服务:AMSstartBootstrapServices(t);Copy
  • 核心服务:
    //核心服务:系统所需要的startCoreServices(t);Copy
  • 其他服务:WMS
    //其他服务:WMS等startOtherServices(t);

文末

AMS的主要作用:

  • 统一调度Activity
  • (1)AMS中的重要数据类:
  • (2)重要变量
  • (3)启动Activity
  • 内存管理
  • (1)关闭而不退出
  • (2)内存不够用时,Activity按优先级县回收后台的Activity,或使用OOM进程回收内存
  • 进程管理

相关内容

热门资讯

FIBA期待杨瀚森表现 最新实... 北京时间6月25日消息,FIBA国际篮联公布了最新一期世界杯预选赛亚太区球队实力榜,中国男篮排在澳大...
收评:创业板指放量反弹涨2.8... 市场冲高回落后,再度震荡拉升。黄白线分化明显,权重股走势较强。量能明显放大,沪深两市成交额3.59万...
巨头财报引爆A股存储芯片板块,... 当地时间6月24日美股盘后, 美光科技(MU.US)公布截至5月31日的2026财年第三财季财报,业...
银行、消金公司助贷余额增速不得... 近日,中国证券报记者从多位业内人士处独家获悉,5月以来,多地金融监管部门对部分中小银行、消金公司下达...
朱鸿接任陈航,担任钉钉科技有限... 消费日报-今朝新闻讯 天眼查显示,6月23日,钉钉科技有限公司发生工商变更,陈航卸任法定代表人、董事...
3日累跌超20%,德创环保:公... 6月25日, 德创环保(603177.SH)公告,公司股票于2026年6月23日、6月24日和6月2...
北京发布2026年第七轮拟供商... 央广网北京6月25日消息(记者门庭婷)6月25日,北京市规划和自然资源委员会网站发布了2026年第七...
开放麦 | 启明创投胡奇:从A... “2026年,创投圈的浪潮再次翻涌:AI从技术概念走进产业深水区,硬科技创业从“小众赛道” 变成“主...
腾讯孙忠怀:在行业转身处 6月24日,2026腾讯视频年度发布在上海举行。腾讯公司副总裁、腾讯在线视频董事长孙忠怀以《在行业转...
加息,突变!美联储,重磅传来!... 美联储政策路径突生变数。 美国商务部经济分析局最新公布的数据显示,5月个人消费支出(PCE)物价指数...
6月合肥上门收金必看!5步避坑... 2026年6月,合肥黄金市场持续高位运行,不少市民翻出家里闲置的旧金饰、投资金条想变现,上门回收因为...
潮汕女富豪挂帅后加码液冷!祥鑫... 潮汕女强人,带着百亿公司加码液冷散热。 6月24日晚间,祥鑫科技(002965.SZ)公告称,公司董...
马斯克向太空要电,GobiX ... 一场关于「去哪里找电」的全球竞赛,正在朝两个方向展开。 作者|周永亮 编辑| 郑玄 「太空光伏是不是...
原料药行业陷入周期低谷 有药企... 每经记者|许立波 每经编辑|魏文艺 “过完年到现在,我们整个团队每个月都在出差,跑遍了亚非拉、欧美市...
家门口筛查白内障!永顺泽家镇暖... 大众卫生报·新湖南客户端6月25日讯(通讯员 彭雪姣)为切实解决辖区老年性白内障患者异地就医奔波、就...
终于等到!油价马上再大跌,这个... 点击添加图片描述(最多60个字) 编辑 各位车主朋友,好消息接二连三! 继6月18日油价大幅下调...
丈量出海新路 世界酒庄影响力指... 长期以来,全球酒庄评价体系由西方机构主导,且大多局限于单一酒种、单一评价维度,这一局面正逐渐被打破。...
峰瑞资本创始合伙人李丰:从资本... “2026年,创投圈的浪潮再次翻涌:AI从技术概念走进产业深水区,硬科技创业从“小众赛道” 变成“主...
原创 A... 迈向成熟,还有茁壮成长的机会。 作者 | 方璐 编辑丨于婞 来源 | 野马财经 2026年6月21日...
为企业解锁出海新通道!亚太中小... 6月24日下午,作为2026年APEC中小企业工商论坛的重要组成部分,亚太中小企业国际化合作发展论坛...