ActivityManagerService源码分析(一)

2024-08-29 07:58

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

前言:

AMS是Android系统服务中很重要的一个,他负责四大组件的启动、切换、调度、生命周期的管理等等,接下来我们根据AMS的启动来分析AMS的源码


1. SystemServer启动AMS

ActivityManagerService是在SystemServer.java中启动并注册的:

private void startBootstrapServices() {......// 启动AMS,见小节2.1mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();// 设置AMSmActivityManagerService.setSystemServiceManager(mSystemServiceManager);//安装App安装器mActivityManagerService.setInstaller(installer);......// 电源管理已经开启,在AMS中初始化PM,见小节3Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitPowerManagement");mActivityManagerService.initPowerManagement();Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);......// 设置应用实例,在系统进程开始的时候,见小节4mActivityManagerService.setSystemProcess();......}

看源码可以看到(我没有贴出来),startBootstrapServices中启动并注册了很多其他的服务,比如:PowerManagerService,DisplayManagerService,LightsService,PackageManagerService,UserManagerService,SensorService(native),这写服务彼此之间有依赖,所以都放在startBootstrapServices方法里面

2. 注册并启动

2.1 startService

文件:SystemServiceManager.java

    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);// 创建服务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);}// 注册mServices.add(service);// 开始服务try {service.onStart();} catch (RuntimeException ex) {throw new RuntimeException("Failed to start service " + name+ ": onStart threw an exception", ex);}return service;} finally {Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);}}

可以看出这方法的作用是创建并且开始一个服务,但是这个服务的类必须是SystemService的子类,于是我们需要传入带有ActivityManagerService的Lifecycle

2.2 Lifecycle

文件:SystemServiceManager.java

    public static final class Lifecycle extends SystemService {private final ActivityManagerService mService;public Lifecycle(Context context) {super(context);// 构建一个新的AMS,见小节2.3mService = new ActivityManagerService(context);}@Overridepublic void onStart() {// 开始服务,2.1中的service.onStart()调用的就是它,见小节2.4mService.start();}public ActivityManagerService getService() {return mService;}}

可以看出Lifecycle是继承SystemService的,并且在构造里构建了AMS,接下来我们来看看AMS的构建函数

2.3 AMS的构建函数

    public ActivityManagerService(Context systemContext) {mContext = systemContext;mFactoryTest = FactoryTest.getMode();mSystemThread = ActivityThread.currentActivityThread();Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());// 创建一个mHandlerThread线程,默认名是:ActivityManagermHandlerThread = new ServiceThread(TAG,android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);mHandlerThread.start();// 创建一个基于ActivityManager线程的HandlermHandler = new MainHandler(mHandlerThread.getLooper());// 创建一个UiHandler线程mUiHandler = new UiHandler();// 用单例的方式创建一个名叫ActivityManager:kill的线程,并且创建一个killHandlerif (sKillHandler == null) {sKillThread = new ServiceThread(TAG + ":kill",android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);sKillThread.start();// 用于杀死进程sKillHandler = new KillHandler(sKillThread.getLooper());}// 构建一个可以延时10秒的前台广播队列mFgBroadcastQueue = new BroadcastQueue(this, mHandler,"foreground", BROADCAST_FG_TIMEOUT, false);// 构建一个可以延时60秒的普通广播队列mBgBroadcastQueue = new BroadcastQueue(this, mHandler,"background", BROADCAST_BG_TIMEOUT, true);mBroadcastQueues[0] = mFgBroadcastQueue;mBroadcastQueues[1] = mBgBroadcastQueue;mServices = new ActiveServices(this);mProviderMap = new ProviderMap(this);mAppErrors = new AppErrors(mContext, this);// 新建一个data/system目录File dataDir = Environment.getDataDirectory();File systemDir = new File(dataDir, "system");systemDir.mkdirs();// 创建一个BatteryStatsService类mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);// 把最新的数据写入硬盘mBatteryStatsService.scheduleWriteToDisk();mOnBattery = DEBUG_POWER ? true: mBatteryStatsService.getActiveStatistics().getIsOnBattery();mBatteryStatsService.getActiveStatistics().setCallback(this);// 创建进程统计服务类,并新建一个data/system/procstats目录mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));// 创建一个应用权限检查类,新建一个data/system/appops.xml文件,并注册对应的回调接口mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,new IAppOpsCallback.Stub() {@Override public void opChanged(int op, int uid, String packageName) {if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {if (mAppOpsService.checkOperation(op, uid, packageName)!= AppOpsManager.MODE_ALLOWED) {runInBackgroundDisabled(uid);}}}});mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));// 创建多用户控制器,user 0是第一个,同时也是唯一开机过程中运行的用户mUserController = new UserController(this);// 获取OpenGL版本,如果没有找到,则默认为0GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",ConfigurationInfo.GL_ES_VERSION_UNDEFINED);mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));// 设置系统的一些默认配置信息mConfiguration.setToDefaults();mConfiguration.setLocales(LocaleList.getDefault());mConfigurationSeq = mConfiguration.seq = 1;// 初始化进程CPU跟踪器mProcessCpuTracker.init();// 解析/data/system/packages-compat.xml文件,当设备屏幕大小不满足APK所需要的大小,// 则从packages-compat.xml都去尺寸,用兼容的方式运行mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);// 根据AMS传入规则,过滤一些IntentmIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);// 用来管理Activity栈mStackSupervisor = new ActivityStackSupervisor(this);// 解释怎样启动ActivitymActivityStarter = new ActivityStarter(this, mStackSupervisor);// 管理最近任务列表mRecentTasks = new RecentTasks(this, mStackSupervisor);//创建一个统计进程使用CPU情况的线程,名叫CpuTrackermProcessCpuThread = new Thread("CpuTracker") {@Overridepublic void run() {while (true) {try {try {synchronized(this) {final long now = SystemClock.uptimeMillis();long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;//Slog.i(TAG, "Cpu delay=" + nextCpuDelay//        + ", write delay=" + nextWriteDelay);if (nextWriteDelay < nextCpuDelay) {nextCpuDelay = nextWriteDelay;}if (nextCpuDelay > 0) {mProcessCpuMutexFree.set(true);this.wait(nextCpuDelay);}}} catch (InterruptedException e) {}updateCpuStatsNow();} catch (Exception e) {Slog.e(TAG, "Unexpected exception collecting process stats", e);}}}};// watchdog添加对AMS的监控Watchdog.getInstance().addMonitor(this);Watchdog.getInstance().addThread(mHandler);......

这个方法会在main thread中被唤醒,但是它需要通过各个handers和其他thread通信,所以要注意明确looper。该构造函数,里面是初始化一些变量,及创建了一些线程,大部分我都进行了注释。

2.4 start

文件:ActivityManagerService.java

    private void start() {// 移除所有的进程组Process.removeAllProcessGroups();// 开始监控进程的CPU使用情况mProcessCpuThread.start();// 注册电池统计服务mBatteryStatsService.publish(mContext);// 注册应用权限检测服务mAppOpsService.publish(mContext);Slog.d("AppOps", "AppOpsService published");// 注册LocalService服务LocalServices.addService(ActivityManagerInternal.class, new LocalService());}

启动ProcessCpuThread,注册电池统计服务,应用权限检测服务和LocalService,其中LocalService继承了ActivityManagerInternal。
小结:创建AMS,启动AMS

3. 初始化PM

3. initPowerManagement

文件:ActivityManagerService.java

    public void initPowerManagement() {// Activity堆栈管理器和电池统计服务初始化PMmStackSupervisor.initPowerManagement();mBatteryStatsService.initPowerManagement();mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");// 该唤醒锁为不计数锁,即无论acquire()多少次,一次release()就可以解锁mVoiceWakeLock.setReferenceCounted(false);}

小结:这主要是在AMS中初始化PM

4. 设置应用实例

4.1 setSystemProcess

文件:ActivityManagerService.java

    public void setSystemProcess() {try {// 以下都是想ServiceManager注册服务ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); // 注册AMS自己ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); // 注册进程统计服务ServiceManager.addService("meminfo", new MemBinder(this)); // 注册内存信息的服务ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); // 注册输出渲染信息的服务ServiceManager.addService("dbinfo", new DbBinder(this)); // 注册输出数据库信息的服务// MONITOR_CPU_USAGE默认为trueif (MONITOR_CPU_USAGE) {ServiceManager.addService("cpuinfo", new CpuBinder(this)); // 输出进程使用CPU的情况}ServiceManager.addService("permission", new PermissionController(this)); // 注册权限管理ServiceManager.addService("processinfo", new ProcessInfoService(this)); // 注册进程信息// 查询名为android的应用信息ApplicationInfo info = mContext.getPackageManager().getApplicationInfo("android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);// 调用installSystemApplicationInfo ,见小节4.2mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());// synchronized (this) {// 创建一个ProcessRecord对象 ,见小节4.5ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);app.persistent = true;app.pid = MY_PID;app.maxAdj = ProcessList.SYSTEM_ADJ;app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);synchronized (mPidsSelfLocked) {mPidsSelfLocked.put(app.pid, app);}updateLruProcessLocked(app, false, null);updateOomAdjLocked();}} catch (PackageManager.NameNotFoundException e) {throw new RuntimeException("Unable to find android system package", e);}}

4.2 installSystemApplicationInfo

文件:ActivityThread.java

    public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {synchronized (this) {// 看SystemService中创建的ContextIml的installSystemApplicationInfo,见小节4.3getSystemContext().installSystemApplicationInfo(info, classLoader);// give ourselves a default profilermProfiler = new Profiler();}}

4.3 ContextIml.installSystemApplicationInfo

文件:ContextImpl.java

    void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {// 调用的是LoadeApk里面的installSystemApplicationInfo,见小节4.4mPackageInfo.installSystemApplicationInfo(info, classLoader);}

4.4 LoadeApk.installSystemApplicationInfo

文件:LoadeApk.java

    void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {// 断言只有packageName为android才能使用assert info.packageName.equals("android");mApplicationInfo = info;mClassLoader = classLoader;}

将ApplicationInfo加入到LoadeApk中,因为SystemService创建LoadeApk时,PKMS并没有完成对手机中文件的解析

4.5 AMS进程管理

文件:ActivityManagerService.java

            ......synchronized (this) {// 调用进程管理函数,见4.6ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);app.persistent = true;app.pid = MY_PID;app.maxAdj = ProcessList.SYSTEM_ADJ;// 将SystemServer对应的ApplicationThread保存到ProcessRecord中app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);synchronized (mPidsSelfLocked) {// 根据ProcessRecord的pid,将ProcessRecord存在mPidsSelfLocked中mPidsSelfLocked.put(app.pid, app);}updateLruProcessLocked(app, false, null);updateOomAdjLocked();}......

4.6 newProcessRecordLocked

文件:ActivityManagerService.java

    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,boolean isolated, int isolatedUid) {String proc = customProcess != null ? customProcess : info.processName;BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();final int userId = UserHandle.getUserId(info.uid);int uid = info.uid;// isolated为falseif (isolated) {......}// 创建一个进程记录对象,见小节4.7final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);// 判断是否为常驻的进程if (!mBooted && !mBooting&& userId == UserHandle.USER_SYSTEM&& (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {r.persistent = true;}// 将ProcessRecord保存在AMS里的mProcessNames里addProcessNameLocked(r);return r;}

4.7 ProcessRecord

文件:ProcessRecord.java

    ProcessRecord(BatteryStatsImpl _batteryStats, ApplicationInfo _info,String _processName, int _uid) {mBatteryStats = _batteryStats;info = _info;isolated = _info.uid != _uid;uid = _uid;userId = UserHandle.getUserId(_uid);processName = _processName;pkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.versionCode));maxAdj = ProcessList.UNKNOWN_ADJ;curRawAdj = setRawAdj = ProcessList.INVALID_ADJ;curAdj = setAdj = verifiedAdj = ProcessList.INVALID_ADJ;persistent = false;removed = false;lastStateTime = lastPssTime = nextPssTime = SystemClock.uptimeMillis();}

这主要是保存一些ProcessRecord里面的属性。
小结:第四节的主要作用就是将一些服务注册到ServiceManger中,包括AMS自己;然后将framework-res-.apk中applicationInfo信息加入到SystemServeice生成的LoadedApk中,同时构建SystemService对应的ProcessRecord,最后通过addProcessNameLocked(r)来把SystemService加入AMS的管理中来。

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



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

相关文章

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

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

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

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

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

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

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

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

锐捷和腾达哪个好? 两个品牌路由器对比分析

《锐捷和腾达哪个好?两个品牌路由器对比分析》在选择路由器时,Tenda和锐捷都是备受关注的品牌,各自有独特的产品特点和市场定位,选择哪个品牌的路由器更合适,实际上取决于你的具体需求和使用场景,我们从... 在选购路由器时,锐捷和腾达都是市场上备受关注的品牌,但它们的定位和特点却有所不同。锐捷更偏向企业级和专