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

2023-11-10 18:40

本文主要是介绍Android的ActivityManagerService(简称AMS)的源码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Android判断Activity是否在AndroidManifest.xml里面注册(源码分析)

Android的PackageManagerService10.0源码解读

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

Android的ActivityManagerService(简称AMS)的源码分析
内容太多,建议收藏
AMS简介

ActivityManagerService是Android系统中一个特别重要的系统服务,也是我们上层APP打交道最多的系统服务之一。ActivityManagerService(以下简称AMS) 主要负责四大组件的启动、切换、调度以及应用进程的管理和调度工作,所有的APP应用都需要 与AMS打交道。
Activity Manager的组成主要分为以下几个部分:

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

AMS是在SystemServer中被添加的, 所以先到SystemServer中查看初始化.

public static void main(String[] args) {new SystemServer().run();}
private void run(){...// Initialize the system context.createSystemContext();// Create the system service manager.mSystemServiceManager = new SystemServiceManager(mSystemContext);mSystemServiceManager.setStartInfo(mRuntimeRestart,mRuntimeStartElapsedTime, mRuntimeStartUptime);LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);// Prepare the thread pool for init tasks that can be parallelizedSystemServerInitThreadPool.get();} finally {traceEnd();  // InitBeforeStartServices}// Start services.try {traceBeginAndSlog("StartServices");startBootstrapServices();startCoreServices();startOtherServices();SystemServerInitThreadPool.shutdown();} catch (Throwable ex) {Slog.e("System", "******************************************");Slog.e("System", "************ Failure starting system services", ex);throw ex;} finally {traceEnd();...}

在SystemServer中,在startBootstrapServices()中去启动了AMS

 private void startBootstrapServices() { ...// Activity manager runs the show.traceBeginAndSlog("StartActivityManager");//启动了AMSmActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService();mActivityManagerService.setSystemServiceManager(mSystemServiceManager);mActivityManagerService.setInstaller(installer); traceEnd(); ...// Now that the power manager has been started, let the activity manager// initialize power management features.traceBeginAndSlog("InitPowerManagement");mActivityManagerService.initPowerManagement();traceEnd();// Set up the Application instance for the system process and get started.traceBeginAndSlog("SetSystemProcess");mActivityManagerService.setSystemProcess();traceEnd();}

AMS是通过SystemServiceManager.startService去启动的,参数是
ActivityManagerService.Lifecycle.class, 首先看看startService方法.

@SuppressWarnings("unchecked")public SystemService startService(String className) {final Class<SystemService> serviceClass;try {serviceClass = (Class<SystemService>)Class.forName(className);} catch (ClassNotFoundException ex) {Slog.i(TAG, "Starting " + className);throw new RuntimeException("Failed to create service " + className+ ": service class not found, usually indicates that the caller should "+ "have called PackageManager.hasSystemFeature() to check whether the "+ "feature is available on this device before trying to start the "+ "services that implement it", ex);}return startService(serviceClass);}
	@SuppressWarnings("unchecked")public <T extends SystemService> T startService(Class<T> serviceClass) {try {final String name = serviceClass.getName();Slog.i(TAG, "Starting " + name);Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);// Create the service.if (!SystemService.class.isAssignableFrom(serviceClass)) {throw new RuntimeException("Failed to create " + name+ ": service must extend " + SystemService.class.getName());}final T service;try {Constructor<T> constructor = serviceClass.getConstructor(Context.class);service = constructor.newInstance(mContext);} catch (InstantiationException ex) {throw new RuntimeException("Failed to create service " + name+ ": service could not be instantiated", ex);} catch (IllegalAccessException ex) {throw new RuntimeException("Failed to create service " + name+ ": service must have a public constructor with a Context argument", ex);} catch (NoSuchMethodException ex) {throw new RuntimeException("Failed to create service " + name+ ": service must have a public constructor with a Context argument", ex);} catch (InvocationTargetException ex) {throw new RuntimeException("Failed to create service " + name+ ": service constructor threw an exception", ex);}startService(service);return service;} finally {Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);}}
 public void startService(@NonNull final SystemService service) {// Register it.mServices.add(service);// Start it.long time = SystemClock.elapsedRealtime();try {service.onStart();} catch (RuntimeException ex) {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);}@Overridepublic void onStart() {mService.start();}@Overridepublic void onBootPhase(int phase) {mService.mBootPhase = phase;if (phase == PHASE_SYSTEM_SERVICES_READY) {mService.mBatteryStatsService.systemServicesReady();mService.mServices.systemServicesReady();}}@Overridepublic 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对象.

最后上几幅图

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

这篇关于Android的ActivityManagerService(简称AMS)的源码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/384558

相关文章

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

Android kotlin语言实现删除文件的解决方案

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的... 目录一、前言二、适用环境三、模板内容1.权限申请2.Activity中的模板一、前言在项目开发过程中,尤

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re