第四章 AMS深入浅出

本文详细介绍了Android系统中ActivityManagerService(AMS)的深入解析,包括AMS的作用、家族图谱、注册流程、关键函数、重要数据结构以及APP启动流程。AMS作为Android系统的核心服务,负责管理四大组件的启动、切换和调度。文中通过对AMS的启动、APP启动流程的深入剖析,揭示了Android系统如何管理应用程序和活动栈,是理解Android系统运行机制的重要篇章。
摘要由CSDN通过智能技术生成

第四章 AMS深入浅出

面试题预览

  1. AMS是什么?⭐⭐⭐⭐⭐
  2. AMS在Android起到什么作用,简单的分析下Android的源码。⭐⭐⭐⭐⭐
  3. 简述ActivityManagerService是什么时候初始化的?⭐⭐⭐
  4. 简述Binder、ActivityManagerNative、ActivityManagerService三者的关系⭐⭐⭐
  5. 简述AMS的注册流程⭐⭐⭐
  6. 简述ActivityThread和ApplicationThread,以及关系和区别⭐⭐⭐
  7. ActivityManagerService和zygote进程通信是如何实现的⭐⭐⭐
  8. 系统是如何存AMS服务对象的,以及应用层如何拿到AMS应用的?⭐⭐
  9. AMS与servicemanage进程是什么关系,app启动流程讲一讲。⭐⭐⭐⭐⭐
  10. 请简述从点击图标到app启动的流程。⭐⭐⭐⭐⭐

1 概述

ActivityManagerService(以后简称AMS)是Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,其职责与操作系统中的进程管理和调度模块相类似。所有的APP应用都需要 与AMS互动。AMS服务架构几个重要组成部分:

  • 服务代理:由ActivityManagerProxy实现,用于与Server端提供的系统服务进行进程间通信;
  • 服务中枢:ActivityManagerNative继承自Binder并实现IActivityManager,它提供了服务接口和Binder接口的相互转化功能,并在内部存储服务代理对像,并提供了getDefault方法返回服务代理 ;
  • Client:由ActivityManager封装一部分服务接口供Client调用。ActivityManager内部通过调用ActivityManagerNative的getDefault方法,可以得到一个ActivityManagerProxy对像的引用,进而通过该代理对像调用远程服务的方法 ;
  • Server:由ActivityManagerService实现,提供Server端的系统服务;

  AMS服务运行在system_server进程中,AMS由SystemServer的ServerThread线程初始化,可以在SystemServer类中找到相关的启动代码。

  Activity启动或停止会通知AMS,AMS决定是否执行动作。当Activity的数量>20时,最早入栈的Activity会被AMS给忘记,从而给新加进来了activity入栈。

2 AMS家族图谱

AMS由ActivityManagerNative(以后简称AMN)类派生,并实现Watchdog.Monitor和BatteryStatsImpl.BatteryCallback接口。而ActivityManagerNative继承自Binder并实现IActivityManager,它提供了服务接口和Binder接口的相互转化功能,并在内部存储服务代理对像,并提供了getDefault方法返回服务代理。

客户端使用ActivityManager类。由于AMS是系统核心服务,很多API不能开放供客户端使用,所以设计者没有让ActivityManager直接加入AMS家族。在ActivityManager类内部通过调用AMN的getDefault函数得到一个ActivityManagerProxy对象,通过它可与AMS通信。

3 AMS注册流程

其中ServiceManager就是一个服务端的角色,而AMS则是一个客户端的角色。

4 AMS的关键函数

AMS的main函数:创建AMS实例,其中最重要的工作是创建Android运行环境,得到一个ActivityThread和一个Context对象。

AMS的setSystemProcess函数:该函数注册AMS和meminfo等服务到ServiceManager中。另外,它为SystemServer创建了一个ProcessRecord对象。由于AMS是Java世界的进程管理及调度中心,要做到对Java进程一视同仁,尽管SystemServer贵为系统进程,此时也不得不将其并入AMS的管理范围内。

AMS的installSystemProviders:为SystemServer加载SettingsProvider。

AMS的systemReady:做系统启动完毕前最后一些扫尾工作。该函数调用完毕后,HomeActivity将呈现在用户面前。 对AMS 调用轨迹分析是我们破解AMS的第一条线,希望读者反复阅读,以真正理解其中涉及的知识点,尤其是和Android运行环境及Context相关的知识。

AMS主要代码位于:

frameworks\base\core\java\android\app

frameworks\base\services\java\com\android\server\am

 

 

5 AMS的重要数据结构

5.1 ActivityRecord

Activity管理的最小单位,它对应着一个用户界面

ActivityRecord是应用层Activity组件在AMS中的代表,每一个在应用中启动的Activity,在AMS中都有一个ActivityRecord实例来与之对应,这个ActivityRecord伴随着Activity的启动而创建,也伴随着Activity的终止而销毁。

5.2 TaskRecord

TaskRecord即任务栈,每一个TaskRecord都可能存在一个或多个ActivityRecord,栈顶的ActivityRecord表示当前可见的界面。一个App是可能有多个TaskRecord存在的,一般情况下,启动App的第一个activity时,AMS为其创建一个TaskRecord任务栈特殊情况,启动singleTask的Activity,而且为该Activity指定了和包名不同的taskAffiffiffinity,也会为该activity创建一个新的TaskRecord。

5.3 ActivityStack

ActivityStack是系统中用于管理TaskRecord的,内部维护了一个ArrayList。ActivityStackSupervisor内部有两个不同的ActivityStack对象:mHomeStack、mFocusedStack,用来管理不同的任务。我们启动的App对应的TaskRecord由非Launcher ActivityStack管理,它是在系统启动第一个app时创建的。

5.4 ActivityStackSupervisor

ActivityStackSupervisor管理着多个ActivityStack,但当前只会有一个获取焦点(Focused)的ActivityStack;

AMS对象只会存在一个,在初始化的时候,会创建一个唯一的ActivityStackSupervisor对象

 

6 AMS的启动流程

系统启动, AMS启动前:

系统启动后Zygote进程第一个fork出SystemServer进程。SystemServer会启动各种服务

启动各种服务是在SystemServer.run()中调用的,该函数首先会设下sys.boot_completed为1,然后设置时区、语言、国家、locale等属性,接着就开始启动各种服务了:

// Start services.
        try{
            traceBeginAndSlog("StartServices");
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        }catch(Throwable ex) {
            Slog.e("System","******************************************");
            Slog.e("System","************ Failure starting system services",ex);
            throwex;
        }finally{
            traceEnd();
        }

进入到SystemServer:main()->run()->startBootstrapServices() 启动引导服务,进而完成AMS的启动。

ZygoteInit.java:main()->forkSystemServer()->Zygote.java:forkSystemServer()->nativeForkSystemServer()->com_android_internal_os_Zygote.cpp:com_android_internal_os_Zygote_nativeForkSystemServer()->ZygoteInit.java->handleSystemServerProcess()

  1. 为SystemServer进程创建Android运行环境,createSystemContext() -> new ActvityThread()-->attach ->getSystemContext ->createSystemContext
  2. 启动AMS
  3. 将SystemServer进程纳入到AMS的进程管理体系中

setSystemProcess()//将framewok-res.apk信息加入到SystemServer进程的LoadedApk中,构建SystemServe进程的ProcessRecord,保存到AMS中,以便AMS进程统一管理installSystemProvider() //安装SystemServer进程中的SettingsProvider.apk

4)AMS启动完成,通知服务或应用完成后续工作,或直接启动新进程。

AMS.systemReady() // 许多服务或应用进程必须等待AMS完成启动工作后,才能启动或进行一些后续工作,AMS就是在SystemReady()中,通知或启动这些等待的服务和应用进程,例如启动桌面。

几个重要的类:

  • Activity.java 所有Activity的父类
  • ActivityManager AMS的客户端,提供给用户可供调用的api
  • ActiveService 控制service启动 重启等
  • ProcessRecord 记录每个进程的信息
  • ActivityRecord activity对象信息的记录
  • ActivityStack 管理activity生命周期和堆栈
  • TaskRecord 任务栈记录,管理一个任务的应用activity
  • ActivityTaskManagerService/ActivityTaskManagerInternal 管理activity的启动和调度

6 APP启动流程

当启动了AMS服务之后,则就会启动Launch应用程序了,如下:

接下来则看一下一个Android应用是如何启动的

6.1 AMS调用startProcessLocked()向zygote发送请求

6.2 调用Procoess中的Start()

其中可以看到里面会传要启动应用的各种信息:

然后跟进去瞅一眼:

6.3 zygoteProcess.start

也就是到了这一步:

6.4 startViaZygote

流程也就到了这:

其中可以看到设置了一系列的参数:

然后再下一步:

6.5 openZygoteSocketIfNeeded:创建Socket,开始死循环,用于等待AMS请求Zygote来创建新的应用程序进程

对应代码:

注意上面是“Zygote主模式”,好,如果这个条件不匹配,则会继续往下执行,如下:

 

好,如果连接成功,则流程会走到了:

而最终的代码在这:

此时我们所熟知的ActivityThread的main()方法就会被调用了,然后整个应用就启动了。

7 Activity的启动

7.1 根Activity的启动

7.1.1 回顾整个Android系统启动流程中Launcher应用程序的流程

这里先回顾一下整个Android系统启动流程的这一步,串一下:

此时我们点击Launch应用中的某个图标,则会启动该应用的根Activity,其整个流程先看一下流程图:

好,依据此流程来看一下对应的源代码:

7.1.2 调用ApplicationThread中ScheduleReceiver()

7.1.3 这里就会sendMessage来创建Application

 

最终会调到这:

 7.1.4 handleReceiver

7.1.5 handleLaunchActivity

 走进去瞅一下它的细节:

 

然后再跟进去:

而对于一些Activity的其它生命周期的启动都是通过ActivityThread中的Handler来实现的:

 

7.2 普通Activity启动:

7.2.1 Intrumentation.execStartActivity()【未跨进程】:

对于Activity的启动我们肯定得要调用startActivity()方法,所以咱们就从这个方法为入口逐一来剖析其里面的机理,还是很复杂的,下面开始:

 

所以接下来看一下Instrumentation的启动细节:

7.2.2 ActivityManagerProxy.startActivity()【未跨进程】:

而这个ActivityManagerNative在之前 https://www.cnblogs.com/webor2006/p/11811650.html分析Binder机制见过,如下:

其实它也是一个典型的AIDL的Binder通信,打开再来瞅一下:

然后它里面还有一个Proxy:

此时就会调用到Proxy中的startActivity()方法进行Binder通讯了:

此时就会通过Binder驱动调用它的Stub的onTransact()的方法,如下:

7.2.3 ActivityManagerService.startActivity()【开始跨进程了】:

此时就会调用ActivityManagerService的startActivity方法,因为它是ActivityManagerNative的具体实现类:

此时,就到了跨进程访问了,在这之前都是在本进程的逻辑,好接下来继续分析:

7.2.4 ActivityStackSupervisor.startActivityMyWait():

其中看注释说明,是切换到用户app的栈了,我们知道Android的Activity是以栈的形式来管理的,所以它是比较核心的了,可以大致看一下它里面有一些栈的管理:

这个栈的管理在之后的分析中还会有提及到,先有个大致印象,先来关注主流程:

而其实又是一个AIDL的过程,进去稍看一下它的细节:

而看一下它具体的实现:

就是从ServiceManager中来找到package相关的服务,标准的AIDL的调用过程,那IPackageManager的具体实现类是哪个呢?其实是这个,也就是继承了IPackageManager中的抽象类Stub的实现类,其实是它:

7.2.5 PackageManagerService.resolveIntent():扫描app,注册组件

那看一下它的resolveIntent()方法:

查看一下这个方法的细节:

然后回到resolveIntent()方法来,则会看到有一个根据优先级来选择最佳的ResolveInfo,如下:

好,这里还得再来说一下PackageManagerService这个很重要的服务,主要是管理包的一些信息,我们知道在apk安装到系统中时,会在/data/app之类的系统目录下存在,而该服务则会扫描注册在清单中的一些包信息,那么看一下构造方法就能找到一些相关的信息,如下:

所以可以看到该服务器就是来扫描一些包的信息用的,而这构造函数的调用是在这里:

所以这也是为啥在之前这块可以看到拿服务就是用的"package"这个key,回忆下:

其实Android的很多核心服务都是这样会往ServiceManager去注册的。

7.2.6 ActivityStackSupervisor.startActivityLocked():验证intent、Class、Permission等,保存将要启动的Activity的Record

好,接下来接着主流程继续:

那看一下它的细节,可以看到各种异常检测,这里截其中一小部分:

最终生成一个ActivityRecord对像来保存相关信息:

7.2.7 ActivityStackSupervisor.startActivityUncheckedLocked():检查将要启动的Activity的launchMode和启动Flag,根据launcheMode和Flag配置task

该方法的实现代码也比较多,就瞅一下它的大致细节既可:

里面真的是非常之复杂,也看不懂,有个大体的了解,重点是了解整个主流程的过程,好继续,直接跳到这方法的最后:

7.2.8 ActvityStack.startActivityLocked:任务栈历史栈配置

它是专门来维护任务栈的进出的,而上面的ActivityStackSupervisor是维护各个栈的信息,职责不一样,那下面来看一下该方法的细节:

在最后:

此时又回到了ActivityStackSupervisor了,如下:

也就是如下:

7.2.9ActivityStack.resumeTopActivityInnerLocked():查找要进入暂停的Activity

这个里面实现的代码理非常之多,只看核心的,在要跳转到新的Activity之前,先会把一些Activity给暂停了,瞅一下这块的核心流程:

然后在跳到新Activity之前,会先暂停当前的Activity,如下:

7.2.10 ActivityStack.startPausingLocked():通过ipc告诉要暂停的Activity进入暂停

此时看一下这个方法的细节:

而prev.app.thread其实就是ActivityThread,而它里面其实是一个IPC的过程,如下:

此时就会到了ActivityThread中的消息处理中心了,如下:

7.2.11 ActivityThread.handlePauseActivity():

下面具体看一下它的实现:

1、正式让之前的Activity暂停:

2、告诉AMS已经暂停完成:

回到这个方法继续执行,就会发现:

而最终会调到ActivityManagerService,如下:

7.2.12 ActivityManagerService.activityPaused():

然后就会调用到ActivityStack.activityPausedLocked()方法。

7.2.13 ActivityStack.activityPausedLocked():

其中这个方法有一个resumeNext参数,传的true,这里想一想就明白其意思,暂停了当前显示的Activity之后,那肯定得要将要跳转的Activity给显示呀,而这个参数就是控制要显示跳转的Activity的逻辑的,如下:

7.2.14 ActivityStackSuperVisor.resumeTopActivitiesLocked():

7.2.15 ActivityStack.resumeTopActivityLocked():验证是否该启动的Activity所在进程和app是否存在,若存在,直接启动,否则,准备创建该进程。

然后在这个方法里面则会有一个关键的逻辑判断,在启动新的Activity时,先判断是否该Activity是在同一个进程:

如果为ture则代码要启动的Activity为同一个进程,这里就不细看了,如果条件不满足则代表进程不存在,需要创建进程,这里瞅一下,如下:

7.2.16 ActivityStackSuperVisor.startSpecificActivityLocked():该进程不存在,创建进程

好,又回到了这个栈管理类了,看一下它的细节:

7.2.17 ActivityManagerService.startProcessLocked():通过Process.start(“android.app.ActivityThread”)启动进程

7.2.18 ActivityThread.main():

当进程被启动之后,则该进程的ActivityThread.main()方法就会被执行,这块就比较熟了。主要是创建一个Looper。 

7.2.19 ActivityThread.attach():

IActivityManager.attachApplication():

而上面的attach的具体实现:

会调用IActivityManager.attachApplication()方法了,此时就会调用ActivityServiceManager.attachApplication(),如下:

然后往这个方法找一下,会有如下核心代码:

7.2.20 ActivityStackSuperVisor.attachApplicationLocked():准备启动应用,先查找MainActivity

此时又回到了这个栈管理大管家,瞅下:

7.2.21 ActivityStackSuperVisor.realStartActivityLocked():IPC通知ActivityThread

7.2.22 ActivityThread.scheduleLaunchActivity():

其中performLaunchActivity方法就是来创建要启动的Activity,稍微看一下细节:

至此关于Activity的启动的主流程就分析完了,太复杂了。可以看到Android底层的代码有很多C/S架构、分模块的思想,真的是博大精深。

8 参考资料

Android10_原理机制系列_AMS之AMS的启动

AMS解析

Android AMS服务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值