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

相关文章

Go标准库常见错误分析和解决办法

《Go标准库常见错误分析和解决办法》Go语言的标准库为开发者提供了丰富且高效的工具,涵盖了从网络编程到文件操作等各个方面,然而,标准库虽好,使用不当却可能适得其反,正所谓工欲善其事,必先利其器,本文将... 目录1. 使用了错误的time.Duration2. time.After导致的内存泄漏3. jsO

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

Spring事务中@Transactional注解不生效的原因分析与解决

《Spring事务中@Transactional注解不生效的原因分析与解决》在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为... 目录1. 引言2. 事务自调用问题重现2.1 示例代码2.2 问题现象3. 为什么事务自调用会失效3

找不到Anaconda prompt终端的原因分析及解决方案

《找不到Anacondaprompt终端的原因分析及解决方案》因为anaconda还没有初始化,在安装anaconda的过程中,有一行是否要添加anaconda到菜单目录中,由于没有勾选,导致没有菜... 目录问题原因问http://www.chinasem.cn题解决安装了 Anaconda 却找不到 An

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用

C++ 各种map特点对比分析

《C++各种map特点对比分析》文章比较了C++中不同类型的map(如std::map,std::unordered_map,std::multimap,std::unordered_multima... 目录特点比较C++ 示例代码 ​​​​​​代码解释特点比较1. std::map底层实现:基于红黑

Spring、Spring Boot、Spring Cloud 的区别与联系分析

《Spring、SpringBoot、SpringCloud的区别与联系分析》Spring、SpringBoot和SpringCloud是Java开发中常用的框架,分别针对企业级应用开发、快速开... 目录1. Spring 框架2. Spring Boot3. Spring Cloud总结1. Sprin

Spring 中 BeanFactoryPostProcessor 的作用和示例源码分析

《Spring中BeanFactoryPostProcessor的作用和示例源码分析》Spring的BeanFactoryPostProcessor是容器初始化的扩展接口,允许在Bean实例化前... 目录一、概览1. 核心定位2. 核心功能详解3. 关键特性二、Spring 内置的 BeanFactory

MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析

《MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析》本文将详细讲解MyBatis-Plus中的lambdaUpdate用法,并提供丰富的案例来帮助读者更好地理解和应... 目录深入探索MyBATis-Plus中Service接口的lambdaUpdate用法及示例案例背景

MyBatis-Plus中静态工具Db的多种用法及实例分析

《MyBatis-Plus中静态工具Db的多种用法及实例分析》本文将详细讲解MyBatis-Plus中静态工具Db的各种用法,并结合具体案例进行演示和说明,具有很好的参考价值,希望对大家有所帮助,如有... 目录MyBATis-Plus中静态工具Db的多种用法及实例案例背景使用静态工具Db进行数据库操作插入