Android的ActivityManagerService(简称AMS) 源码分析

throw new RuntimeException("Failed to start service " + service.getClass().getName()

  • “: onStart threw an exception”, ex);

}

warnIfTooLong(SystemClock.elapsedRealtime() - time, service, “onStart”);

}

startService方法很简单,是通过传进来的class然后反射创建对应的service服务。所以此处创建的是Lifecycle的实例, 然后通过startService启动了AMS服务. 再去看看ActivityManagerService.Lifecycle这个类的构造方法.

public static final class Lifecycle extends SystemService {

private final ActivityManagerService mService;

public Lifecycle(Context context) {

super(context);

mService = new ActivityManagerService(context);

}

@Override

public void onStart() {

mService.start();

}

@Override

public void onBootPhase(int phase) {

mService.mBootPhase = phase;

if (phase == PHASE_SYSTEM_SERVICES_READY) {

mService.mBatteryStatsService.systemServicesReady();

mService.mServices.systemServicesReady();

}

}

@Override

public void onCleanupUser(int userId) {

mService.mBatteryStatsService.onCleanupUser(userId);

}

public ActivityManagerService getService() {

return mService;

}

}

AMS初始化做了很多操作,具体的可以去看看ActivityManagerService,

具体的有

  • mSystemThread = ActivityThread.currentActivityThread();//获取当前的 ActivityThread

  • mUiContext = mSystemThread.getSystemUiContext();//赋值mUiContext

  • 创建Handler线程,用来处理handler消息

  • mUiHandler = mInjector.getUiHandler(this);//处理ui相关msg的Handler

  • 管理AMS的一些常量,厂商定制系统就可能修改此处 mConstants = new ActivityManagerConstants(this, mHandler)

  • 初始化管理前台、后台广播的队列, 系统会优先遍历发送前台广播 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, “foreground”, BROADCAST_FG_TIMEOUT, false);

  • 初始化管理Service的 ActiveServices对象 mServices = new ActiveServices(this);

  • mProviderMap = new ProviderMap(this);//初始化Provider的管理者

  • mAppErrors = new AppErrors(mUiContext, this);//初始化APP错误日志的打印器

  • 创建电池统计服务, 并输出到指定目录 File dataDir = Environment.getDataDirectory();

  • 创建进程统计分析服务,追踪统计哪些进程有滥用或不良行为 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();

  • 加载Uri的授权文件 mGrantFile = new AtomicFile(new File(systemDir, “urigrants.xml”), “uri- grants”);

  • 负责管理多用户 mUserController = new UserController(this);

  • vr功能的控制器 mVrController = new VrController(this);

  • 初始化OpenGL版本号

  • 管理ActivityStack的重要类,这里面记录着activity状态信息,是AMS中的核心类 mStackSupervisor = createStackSupervisor();

  • //根据当前可见的Activity类型,控制Keyguard遮挡,关闭和转换。 Keyguard就是我们的锁 屏相关页面mKeyguardController = mStackSupervisor.getKeyguardController();

  • 管理APK的兼容性配置 解析/data/system/packages-compat.xml文件,该文件用于存储那些需要考虑屏幕尺寸的APK信 息,mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);

  • Intent防火墙,Google定义了一组规则,来过滤intent,如果触发了,则intent会被系统丢 弃,且不会告知发送者 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);

  • 这是activity启动的处理类,这里管理者activity启动中用到的intent信息和flag标识,也 和stack和task有重要的联系 mActivityStartController = new ActivityStartController(this);

  • 启动一个线程专门跟进cpu当前状态信息,AMS对当前cpu状态了如指掌,可以更加高效的安排其他工 作

  • 看门狗,监听进程。这个类每分钟调用一次监视器。 如果进程没有任何返回就杀掉 Watchdog.getInstance().addMonitor(this)

  • 等待mProcessCpuThread完成初始化后, 释放锁,初始化期间禁止访问 mProcessCpuInitLatch.await()

setSystemProcess()做的事情
  1. 注册服务:首先将ActivityManagerService注册到ServiceManager中,其次将几个与系统性能调试相关的服务注册到ServiceManager

  2. 查询并处理ApplicationInfo。首先调用PackageManagerService的接口,查询包名为android的应用程序的ApplicationInfo信息,对应于framework-res.apk。然后以该信息为参数调用ActivityThread上的installSystemApplicationInfo方法。

  3. 创建并处理ProcessRecord。调用ActivityManagerService上的newProcessRecordLocked,创建一个ProcessRecord类型的对象,并保存该对象的信息

AMS是什么?

1.从java角度来看,ams就是一个java对象,实现了Ibinder接口,所以它是一个用于进程之间通信的

接口,这个对象初始化是在systemServer.java 的run()方法里面.

2.AMS是一个服务: ActivityManagerService从名字就可以看出,它是一个服务,用来管理Activity,而且是一个系统服务,就是包管理服务,电池管理服务,震动管理服务等。

3.AMS是一个Binder ams实现了Ibinder接口,所以它是一个Binder,这意味着他不但可以用于进程间通信,还是一个 线程,因为一个Binder就是一个线程。

如果我们启动一个hello World安卓用于程序,里面不另外启动其他线程,这个里面最少要启动4个 线程.

  1. main线程,只是程序的主线程,也是日常用到的最多的线程,也叫UI线程,因为android的组件是非线程安全的,所以只允许UI/MAIN线程来操作。

2.GC线程,java有垃圾回收机制,每个java程序都有一个专门负责垃圾回收的线程

3.Binder1 就是我们的ApplicationThread,这个类实现了Ibinder接口,用于进程之间通信,具体 来说,就是我们程序和AMS通信的工具

4.Binder2 就是我们的ViewRoot.W对象,他也是实现了IBinder接口,就是用于我们的应用程序和 wms通信的工具。

wms就是WindowManagerServicer ,和ams差不多的概念,不过他是管理窗口的系统服务。

public class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {}

AMS相关重要类介绍
ProcessRecord 数据结构
第一类数据:描述身份的数据
  • ApplicationInfo info:AndroidManifest.xml中定义的Application信息

  • boolean isolated:是不是isolated进程

  • int uid:进程uid

  • int userId:这个是android做的多用户系统id,就像windows可以登录很多用户一样,android

也希望可以实现类似的多用户

  • String processName:进程名字,默认情况下是包名

  • IApplicationThread thread:这个很重要,它是ApplicationThread的客户端,AMS就是通过这

个对象给apk进程发送异步消息的(管理四大组件的消息),所以只有这个对象不为空的情况下, 才代表apk进程可是使用了

  • int pid:进程的pid
第二类数据:描述进程中组件的数据
  • pkgList:进程中运行的包

  • ArraySet pkgDeps:进程运行依赖的包

  • ArrayList activities:进程启动的所有的activity组件记录表

  • ArraySet services:进程启动的所有的service组件记录表

  • ArraySet receivers:广播接收器的记录表

  • ArrayList conProviders:使用ContentProvider的客户端记录表

  • 10.BroadcastRecord curReceiver:当前进程正在执行的广播

第三类数据:描述进程状态的数据
  • int maxAdj:进程的adj上限(adjustment)

  • int curRawAdj:当前正在计算的adj,这个值有可能大于maxAdj

  • int setRawAdj:上次计算的curRawAdj设置到lowmemorykiller系统后的adj

  • int curAdj:当前正在计算的adj,这是curRawAdj被maxAdj削平的值

  • int pssProcState:pss进程状态

第四类数据:和pss相关的数据

VSS- Virtual Set Size 虚拟耗用内存(包含共享库占用的内存) RSS- Resident Set Size 实际使用物理内存(包含共享库占用的内存) PSS- Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存) USS- Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存) 一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS

  • .long initialIdlePss:初始化pss

  • .long lastPss:上次pss

  • .long lastSwapPss:上次SwapPss数据

  • long lastCachedPss:上次CachedPss数据

  • long lastCachedSwapPss:上次CachedSwapPss数据

第五类数据:和时间相关的数据
  • long lastActivityTime:上次使用时间

  • long lastStateTime:上次设置进程状态的时间

  • long fgInteractionTime:变成前台的时间

第六类数据:crash和anr相关的数据
  • IBinder.DeathRecipient deathRecipient:apk进程退出运行的话,会触发这个对象的

binderDied()方法,来回收系统资源

  • boolean crashing:进程已经crash

  • Dialog crashDialog:crash对话框

  • Dialog anrDialog:anr显示对话框

  • String waitingToKill:后台进程被kill原因

第七类数据:和instrumentation相关的数据

instrumentation 也可以说是apk的一个组件,如果我们提供的话,系统会默认使用Instrumentation.java类,按照我们一般的理解,UI 线程控制activity的生命周期,是是直接调用Activity类的方法,时间是这样子的,UI线程调用的是instrumentation的方法,由它在调用Activity涉及生命周期的方法,所有如果我们覆写了instrumentation的这些方法,就可以了解所有的Activity的生命周期了.

  • ComponentName instrumentationClass:AndroidManifest.xml中定义的instrumentation信 息

  • ApplicationInfo instrumentationInfo:instrumentation应用信息

  • String instrumentationProfileFile:instrumentation配置文件

  • IInstrumentationWatcher instrumentationWatcher:instrumentation监测器

第八类数据:电源信息和调试信息
  • BatteryStatsImpl mBatteryStats:电量信息

  • BatteryStatsImpl.Uid.Proc curProcBatteryStats:当前进程电量信息

  • boolean debugging:处于调试中

  • boolean waitedForDebugger:等待调试

  • Dialog waitDialog:等待对话框

ProcessRecord容器
内部四大组件记录表的容器

组件运行才是进程存在的意义,由于android系统进程间的无缝结合,所以系统需要控制到组件级别,所有的组件信息都需要映射到系统,一个ActivityRecord记录对应一个Activity的信息,一个ServiceRecord记录对应一个Service的信息,一个ConnectionRecord记录对应一个bind service的客户端信息,一个ReceiverList对应处理同一事件的一组广播,一个ContentProviderRecord记录对应一个ContentProvider信息,一个ContentProviderConnection对应一个进程中的所有ContentProvider客户端. activity记录:activities:ActivityRecord的容器,进程启动的所有的activity组件记录表 service记录

  • services:ServiceRecord的容器,进程启动的所有的service组件记录表

  • executingServices:正在运行(executing)的ServiceRecord是怎么定义的?首先需要明确的是系统是怎么控制组件的?发送消息给apk进程,apk进程处理消息,上报消息完成,这被定义为一个完整的执行过程,因此正在执行(executing)被定义为发送消息到上报完成这段时间

  • connections:ConnectionRecord容器,绑定service的客户端记录表

广播接收器记录:receivers:ReceiverList容器,广播接收器的记录表 ContentProvider记录:

  • pubProviders:名字到ContentProviderRecord的映射容器,pub是publish(发布)的意思,

ContentProvider需要安装然后把自己发布到系统(AMS)中后,才能使用,安装指的是apk进程 加载ContentProvider子类、初始化、创建数据库等过程,发布是将ContentProvider的binder客 户端注册到AMS中

  • contProviders:ContentProviderConnection容器,使用ContentProvider的客户端记录表
与Activity管理有关的数据结构
ActivityRecord

ActivityRecord,源码中的注释介绍:An entry in the history stack, representing an activity. 翻译:历史栈中的一个条目,代表一个activity。 ActivityRecord中存在着大量的成员变量,包含了一个Activity的所有信息。 ActivityRecord中的成员变量task表示其所在的TaskRecord,由此可以看出:ActivityRecord与TaskRecord建立了联系, \frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java

TaskRecord

TaskRecord,内部维护一个 ArrayList 用来保存ActivityRecord \frameworks\base\services\core\java\com\android\server\am\TaskRecord.java 可以看到TaskRecord中使用了一个ArrayList来保存所有的ActivityRecord。 同样,TaskRecord中的mStack表示其所在的ActivityStack。 startActivity()时也会创建一个TaskRecord.

ActivityStarter

frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

ActivityStack

ActivityStack,内部维护了一个 ArrayList ,用来管理`TaskRecord 可以看到ActivityStack使用了一个ArrayList来保存TaskRecord。 另外,ActivityStack中还持有ActivityStackSupervisor对象,这个是用来管理ActivityStacks的。 ActivityStack是由ActivityStackSupervisor来创建的,实际ActivityStackSupervisor就是用来管理ActivityStack的.

ActivityStackSupervisor

ActivityStackSupervisor,顾名思义,就是用来管理ActivityStack的 frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java ActivityStackSupervisor内部有两个不同的ActivityStack对象:mHomeStack、mFocusedStack,用来管理不同的任务。 ActivityStackSupervisor内部包含了创建ActivityStack对象的方法。 AMS初始化时会创建一个ActivityStackSupervisor对象.

最后上几幅图

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

总结

其实客户端开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

Android大厂面试真题全套解析

2017-2020字节跳动Android面试真题解析PDF
然而Android架构学习进阶是一条漫长而艰苦的道路,不能靠一时激情,更不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:贵在坚持!

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img
容对你有帮助,可以添加V获取:vip204888 (备注Android)**
[外链图片转存中…(img-xFHY3150-1712778081311)]

总结

其实客户端开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

[外链图片转存中…(img-785nvdkb-1712778081312)]

[外链图片转存中…(img-ySbVqY2Y-1712778081312)]
然而Android架构学习进阶是一条漫长而艰苦的道路,不能靠一时激情,更不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:贵在坚持!

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-pVZd1Khv-1712778081312)]

  • 18
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值