AMS的启动和原理

AMS的诞生

请先看完两篇基础博客 Android Binder机制从开机到应用呈现经历了什么

AMS(ActivityManagerService)是Android系统中最为重要的几个Service之一。我在另一篇博客 从开机到应用呈现经历了什么 中曾讲述过系统在启动过程中各项系统服务都是怎样起来的。其中说到在zygote进程启动的开始阶段会通过ZygoteInit.preload()预加载一些资源,其中就包括框架层,而框架层要加载哪些类呢?这些要预加载的类由一个列表管理着,位置在 frameworks/base/preloaded-classesclasses, 经过系统编译后,会生成 /system/etc/preloaded-classes,zygote进程预加载时正是按照system/etc下的列表加载。我们可以在 cs.android.com 上查看到frameworks下的列表,如下便是一部分

frameworks/base/preloaded-classesclasses是android系统源码的一部分,但是在android sdk 的source (即框架层源码)里是没有preloaded-classesclasses的,因为sdk是面向上层开发者的,所以这部分系统开发相关的就没有出现在sdk的源码里。系统编译时,frameworks/base/preloaded-classesclasses 在 frameworks/base/tools/preload 的过滤规则下被重新转化,最终形成 /system/etc/preloaded-classes。过滤规则列举几条如下:

基础门槛:只考虑属于系统 BOOTCLASSPATH 的类。

效率优先:加载耗时超过 1250微秒 的"慢"类,优先入选。

收益为王:至少被 10个及以上 进程使用过的"大众"类,入选。

排除干扰:那些会启动后台服务或线程,可能干扰 Zygote 进程的类,会被禁用

由于android.app下的类属于核心类,所以最终也会出现在 system/ect/preloaded-classes里。请注意,这里面就包含了SystemServiceRegistry 。咱们去看一下它的代码:

大家看到了吧,在它的static块(意味着只要该类被加载,这块代码就会被执行)里有一个看起来像是注册ActivityManager的逻辑,但是仔细看就会发现,第三个参数其实是一个ServiceFetcher,其中该Fetcher的createService()会返回一个ActivityManager实例。

至此,追踪路径都很单一,接下来就是看看谁调用 getSystemServiceFetcher 了,出现了两处,也都在 SystemServiceRegistry 里,一处是public static Object getSystemService(@NonNull ContextImpl ctx, String name) ,另一处是public static @Nullable Object getSystemServiceWithNoContext(@NonNull String name),不过后者没有地方调用,所以继续追踪

public static Object getSystemService(@NonNull ContextImpl ctx, String name) {

final ServiceFetcher<?> fetcher = getSystemServiceFetcher(name);

if (fetcher == null) {

return null;

}

final Object ret = fetcher.getService(ctx);

if (sEnableServiceNotFoundWtf && ret == null) {

// Some services do return null in certain situations, so don't do WTF for them.

switch (name) {

case Context.CONTENT_CAPTURE_MANAGER_SERVICE:

case Context.APP_PREDICTION_SERVICE:

...

return null;

...

}

Slog.wtf(TAG, "Manager wrapper not available: " + name);

return null;

}

return ret;

}

可以看到,哪个地方调用了getSystemService,就会导致生成ActivityManager。不过查看CachedServiceFetcher的源码其实就可以知道,每个ContextImp每次调用getSystemService返回的都是同一个ActivityManager实例。

在系统启动时,会如上代码截图中那样执行很多 registerService,大家一定要注意,它的第三个参数是一个CachedServiceFetcher,实际在注册时是没有生成XXXManager的,这个方法说是注册 CachedServiceFetcher 兴许更合适。当所有注册完成后,到底注册了多少个 CachedServiceFetcher 也就确定了,比如说 99 个。所有这些 CachedServiceFetcher 都被分配了一个编号(即SystemServiceRegistry 的 static int sServiceCacheSize)

),这个编号是连续的,每注册一个CachedServiceFetcher ,这个编号就+1。那么注册完99个,也就有 编号从0 到 98 的99个CachedServiceFetcher 。咱们假设,AMS对应的编号是5。之后,才可能会产生第一个 ContextImp ,而每个 ContextImp 会有一个 final Object[] mServiceCache ,元素个数就是 sServiceCacheSize 个。懂了吧:如果系统有99条系统服务,那么每个 ContextImp 就都有一个含有 99 个元素的 mServiceCache。当一个 ContextImp 第一次通过 getSystemService 获取一个服务时(例如ActivityManager),就会去自己的 mServiceCache 里查找(仍以ActivityManager为例),于是去索引为5的位置去找,发现是null,于是生成一个ActivityManager,然后放入位置5,以后再获取ActivityManager就直接返回。所以对于每个ContextImp来说,它每次调用getSystemService获取的同一类型 XXXManager 服务都是同一个实例。

好了,到了这一步咱们做一个总结:谁会调用 ContextImpl 里的 public Object getSystemService(String name) ,谁就会触发ActivityManager的创建!

啊!也不对啊!咱们在说 ActivityManagerService(AMS),怎么说起 ActivityManager 了?!ActivityManagerService是system_server进程中真正的服务,是执行请求的最终执行者,整个系统里就只有一条,而ActivityManager是应用层中ActivityManagerService的代理,应用层需要通过ActivityManager来和AMS打交道。

AMS需要基于框架层的资源才能运行。所以zygote是在加载完框架层资源之后,才通过forkSystemServer()生成system_server进程,system_server 再通过 startBootstrapServices() 开启各类公共服务,其中有一段

复制代码
mActivityManagerService = mSystemServiceManager.startService(
        ActivityManagerService.Lifecycle.class).getService();

SystemServiceManager.startService() 方法利用 Java 反射机制,根据传入的 ActivityManagerService.Lifecycle.class 参数,动态地创建了一个 Lifecycle 对象。它的 getService() 方法则会返回我们在 Lifecycle 内部已经创建好的 ActivityManagerService 实例。这得益于 Lifecycle 是 ActivityManagerService 的一个静态内部类,它继承了 SystemService,充当了 AMS 与 SystemServiceManager 之间的桥梁。其核心在于它的构造函数:

复制代码
public static final class Lifecycle extends SystemService {
    private final ActivityManagerService mService;
    public Lifecycle(Context context) {
        super(context);
        // 真正创建 AMS 实例的地方!
        mService = new ActivityManagerService(context);
    }

    public ActivityManagerService getService() {
        return mService;
    }
}

至此,AMS就创建完成了,但是还不够,还需要system_server通过 setSystemProcess() 将AMS注册到ServiceManager中,之后其他进程才能使用AMS。

其他服务,比如PMS、WiFiManagerService等也都是相同原理。

在所有服务都准备完毕后,AMS执行systemReady() 方法,这个方法标志着 AMS 已经准备就绪,可以对外提供服务。它会发出一个 Home 应用的 Intent,最终启动我们看到的 Launcher 桌面,标志着系统启动完成。再之后,Activity、Service等这些ContextImpl就可以通过getSystemService获取到ActivityManager。

zygote进程先把框架层资源加载起来,其中就包括可以产生 XXXManager的各类CachedServiceFetcher,之后fork出system_server进程,system_server进程启动AMS服务并将其注册到ServiceManager。再之后,任何应用进程里的ContextImpl都可以通过getSystemService触发CachedServiceFetcher生成XXXManager来使用各项公共服务。

AMS的作用

1、四大组件生命周期管理

统一调度 Activity、Service、BroadcastReceiver、ContentProvider 的启动、运行、停止、销毁。

App 中 onCreate()、onResume() 等方法,都是由 AMS 通过 Binder 回调触发的。

2、任务栈(Task)管理

维护每个应用的 Activity 任务栈,支持 standard、singleTop、singleTask、singleInstance 等启动模式。

决定按返回键时回到哪个 Activity,以及多任务界面中应用切回时的恢复行为。

3、进程管理与优先级分配

为每个应用进程计算 oom_adj 值(前台/可见/服务/缓存/空进程等)。

与内核的 Low Memory Killer (LMK) 协作,在内存不足时按优先级回收进程。

4、ANR 监测与处理

对广播(10s/60s)、输入事件(5s)、服务启动(20s)等关键操作设置超时计时。

超时后主动采集进程堆栈,生成 /data/anr/traces.txt,弹 ANR 对话框。

5、权限校验

在启动 Activity/Service、发送广播时,检查调用方是否拥有相应权限(通过与 PackageManagerService 协作)。

6、应用启动优化

维护进程缓存、记录应用使用频率(与 UsageStatsService 配合),辅助系统做出更快的启动决策。

7、系统就绪与 Launcher 启动

在系统服务全部启动完成后,发送 CATEGORY_HOME Intent,启动桌面应用。

相关推荐
齊家治國平天下4 个月前
Android 14 系统中 Tombstone 深度分析与解决指南
android·crash·系统服务·tombstone·android 14
Just_Paranoid6 个月前
【TaskStackListener】Android 中用于监听和响应任务栈
android·ams·task·taskstack
胡斌附体7 个月前
linux docker 离线 安装
linux·docker·卸载·自启动·离线安装·系统服务
凯文的内存10 个月前
Android14 app被冻结导致进程间通信失败
android·oomadjuster·activitymanager·freezapp·进程保活
图王大胜1 年前
Android Framework AMS(17)APP 异常Crash处理流程解读
android·app·异常处理·ams·crash·binderdied·讣告
图王大胜1 年前
Android Framework AMS(10)广播组件分析-1
android·framework·应用·组件·broadcast·ams·广播
图王大胜2 年前
Android Framework AMS(05)startActivity分析-2(ActivityThread启动到Activity拉起)
android·framework·ams·startactivity
图王大胜2 年前
Android Framework AMS(04)startActivity分析-1(am启动到ActivityThread启动)
android·framework·ams·activity·startactivity
图王大胜2 年前
Android Framework AMS(01)AMS启动及相关初始化1-4
android·framework·ams·systemserver