ActivityManagerService原理分析

2024-04-19 16:18

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

一.概述

ActivityManagerService是Framework层的核心服务之一,ActivityManagerService是Binder的子类,它的功能主要以下三点:

  • 四大组件的统一调度
  • 进程管理
  • 内存管理

二.ActivityManagerService中的重要变量

  • static final int MAX_ACTIVITYS =20;系统允许的最大后台activity的数目
  • static final int MAX_RECENT_TASK=20; 系统最多存储20个任务栈
  • static final int MAX_HIDDEN_APP=15;系统允许处于hidden状态的进程数目的最大值,超过这个值后,Ams会杀死掉优先级较低的进程
  • ActivityStackSupervisor mStackSupervisor; 通过这个类管理ActivityStacks
  • final ActiveServices mServices; 服务的管理类,管理服务的所有的逻辑
  • final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 前台/后台广播队列
  • private final RecentTasks mRecentTasks; 最近的任务的意图列表
  • final ProcessMap mProcessNames = new ProcessMap(); 当前正在运行的所有进程列表
  • final ArrayList mLruProcesses = new ArrayList();最近使用的进程列表
  • final ArrayList mProcessesToGc = new ArrayList();一旦事情闲置,应该gc的进程列表
  • final HashMap

三.ActivityManagerService的启动过程

ActivityManagerService的启动是在systemserver进程的startBootstrapServices方法中启动的.下面通过源码来分析这个启动过程.
step1.systemserver.startBootstrapServices

private void startBootstrapServices() {// Activity manager runs the show.mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();mActivityManagerService.setSystemServiceManager(mSystemServiceManager);mActivityManagerService.setInstaller(installer);
}

这里调用mSystemServiceManager.startService()来帮助处理,不过这里启动的是ActivityManagerService.Lifecycle类

setp2.SystemService startService

 public SystemService startService(String className) {final Class<SystemService> serviceClass;try {
//通过类加载将类加载进内存serviceClass = (Class<SystemService>)Class.forName(className);} catch (ClassNotFoundException ex) {}//调用startService(serviceClass)进一步处理return startService(serviceClass);}public <T extends SystemService> T startService(Class<T> serviceClass) {try {final String name = serviceClass.getName();final T service;try {//通过反射创建serviceConstructor<T> constructor = serviceClass.getConstructor(Context.class);service = constructor.newInstance(mContext);} // Register it.mServices.add(service);// Start it.try {启动serviceservice.onStart();} catch (RuntimeException ex) {}return service;} }

因为这里启动的是ActivityManagerService.Lifecycle类,调用ActivityManagerService.Lifecycle类的start方法来启动,下面就看看这个类.
step3.ActivityManagerService.Lifecycle

 public static final class Lifecycle extends SystemService {private final ActivityManagerService mService;public Lifecycle(Context context) {super(context);
这个类创建对象的同时就创建出了ActivityManagerServicemService = new ActivityManagerService(context);}@Overridepublic void onStart() {//启动ActivityManagerServicemService.start();}public ActivityManagerService getService() {return mService;}}

从上面的代码可以看出,这个类实际上就是帮我们创建出ActivityManagerService的对象,并且调用start方法开启服务.下面在看看ActivityManagerService在创建的时候做了什么.

step4.ActivityManagerService的构造方法

public ActivityManagerService(Context systemContext) {mContext = systemContext;mFactoryTest = FactoryTest.getMode();mSystemThread = ActivityThread.currentActivityThread();Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());mHandlerThread = new ServiceThread(TAG,android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);mHandlerThread.start();//创建处理主要逻辑的handermHandler = new MainHandler(mHandlerThread.getLooper());//创建处理UI的handler,比如处理无响应的对话框,弹出debug模式的对话框mUiHandler = new UiHandler();//创建存放前台和后台广播的广播队列mFgBroadcastQueue = new BroadcastQueue(this, mHandler,"foreground", BROADCAST_FG_TIMEOUT, false);mBgBroadcastQueue = new BroadcastQueue(this, mHandler,"background", BROADCAST_BG_TIMEOUT, true);mBroadcastQueues[0] = mFgBroadcastQueue;mBroadcastQueues[1] = mBgBroadcastQueue;//创建管理service的类mServices = new ActiveServices(this);//创建管理provider的类mProviderMap = new ProviderMap(this);在ams服务之外创建电池统计服务// TODO: Move creation of battery stats service outside of activity manager service.//创建system目录File dataDir = Environment.getDataDirectory();File systemDir = new File(dataDir, "system");systemDir.mkdirs();//创建电池服务mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);mBatteryStatsService.getActiveStatistics().readLocked();mBatteryStatsService.scheduleWriteToDisk();mOnBattery = DEBUG_POWER ? true: mBatteryStatsService.getActiveStatistics().getIsOnBattery();mBatteryStatsService.getActiveStatistics().setCallback(this);//创建跟踪长期执行流程以寻找滥用等糟糕的应用行为的服务mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));//创建关于和控制应用程序操作的信息的服务mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));// User 0 is the first and only user that runs at boot.//UserHandle表示一个用户mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));mUserLru.add(UserHandle.USER_OWNER);updateStartedUserArrayLocked();GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",ConfigurationInfo.GL_ES_VERSION_UNDEFINED);mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));//配置信息mConfiguration.setToDefaults();mConfiguration.setLocale(Locale.getDefault());mConfigurationSeq = mConfiguration.seq = 1;mProcessCpuTracker.init();//用户要求以屏幕尺寸兼容模式运行的软件包mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);//用于启动最近的任务的意图列表mRecentTasks = new RecentTasks(this);//管理Activity的类,通过这个运行所有的ActivityStack,辅助启动startactivitymStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);//重新启动时保存最近的任务信息mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);//运行时cpu用于收集线程mProcessCpuThread = 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.getInstance().addMonitor(this);Watchdog.getInstance().addThread(mHandler);}

acitivtymanagerservie的构造函数主要初始化了四大组件的管理类,以及处理主要逻辑的mHandler和处理ui相关的mUiHandler ,比如弹出anr等对话框.

Step5.ActivityManagerService.start()

   private void start() {
//删除所有的进程组,确保刚启动的时候是没有进程的Process.removeAllProcessGroups();将CPU用来收集线程的线程启动mProcessCpuThread.start();
启动电池服务mBatteryStatsService.publish(mContext);
启动关于和控制应用程序操作的信息的服务mAppOpsService.publish(mContext);类似servermanger,只不过这个是用于当前进程LocalServices.addService(ActivityManagerInternal.class, new LocalService());}

到这一步ActivityManagerService服务就真正的开启了,就会开始真正的执行前面说的3个主要功能了.

四.主要功能之一的四大组件的统一调度

ActivityManagerService最主要的功能就是统一的管理者activity,service,broadcast,provider的创建,运行,关闭.我们在应用程序中启动acitivity,关闭acitiviy等操作最终都是要通过ams来统一管理的.这个过程非常的复杂,不是一下子可以讲的清楚的,我这里推荐老罗的博客来讲解四大组件的启动过程:

  • Android应用程序内部启动Activity过程(startActivity)的源代码分析
  • Android系统在新进程中启动自定义服务过程(startService)的原理分析
  • Android应用程序注册广播接收器(registerReceiver)的过程分析
  • Android应用程序发送广播(sendBroadcast)的过程分析
  • Android应用程序组件Content Provider简要介绍和学习计划

五.主要功能之一的内存管理

我们知道当一个进程中的acitiviy全部都关闭以后,这个空进程并不会立即就被杀死.而是要等到系统内存不够时才会杀死.但是实际上ActivityManagerService并不能够管理内存,android的内存管理是Linux内核中的内存管理模块和OOM进程一起管理的.Android进程在运行的时候,会通过Ams把每一个应用程序的oom_adj值告诉OOM进程,这个值的范围在-16-15,值越低说明越重要,越不会被杀死.当发生内存低的时候,Linux内核内存管理模块会通知OOm进程根据AMs提供的优先级强制退出值较高的进程.因此Ams在内存管理中只是扮演着一个提供进程oom_adj值的功能.真正的内存管理还是要调用OOM进程来完成.下面通过调用Activity的finish()方法来看看内存释放的情况.

当我们手动调用finish()方法或者按back键时都是会关闭activity的,,在调用finish的时候只是会先调用ams的finishActivityLocked方法将当前要关闭的acitiviy的finish状态设置为true,然后就会先去启动新的acitiviy,当新的acitiviy启动完成以后就会通过消息机制通知Ams,Ams在调用activityIdleInternalLocked方法来关闭之前的acitiviy.下面就看看activityIdleInternalLocked的源码

ActivityStackSupevis.activityIdleInternalLocked

 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,Configuration config) {//所有要暂停的activityArrayList<ActivityRecord> stops = null;//所有要finish的activityArrayList<ActivityRecord> finishes = null;ArrayList<UserState> startingUsers = null;int NS = 0;int NF = 0;boolean booting = false;boolean activityRemoved = false;if (allResumedActivitiesIdle()) {if (r != null) {
1.通知所有需要内存回收的进程进行内存回收(这些进程都保存在mProgressToGc列表中)mService.scheduleAppGcsLocked();}2.  分别拿到所有要stop和finish的activity存放在stops和finishs容器中,然后将记录清空stops = processStoppingActivitiesLocked(true);NS = stops != null ? stops.size() : 0;if ((NF = mFinishingActivities.size()) > 0) {finishes = new ArrayList<>(mFinishingActivities);mFinishingActivities.clear();}if (mStartingUsers.size() > 0) {startingUsers = new ArrayList<>(mStartingUsers);mStartingUsers.clear();}3. 停止stops中的所有activityfor (int i = 0; i < NS; i++) {r = stops.get(i);final ActivityStack stack = r.task.stack;if (stack != null) {if (r.finishing) {stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);} else {stack.stopActivityLocked(r);}}}4. 销毁finishs中的所有activityfor (int i = 0; i < NF; i++) {r = finishes.get(i);final ActivityStack stack = r.task.stack;if (stack != null) {activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");}}5.该步骤内部真正地进行内存回收工作,包括杀死不必要的进程
mService.trimApplications();return r;}

在这个方法中除了第一步通知客户进程调用GC来主动回收内存以外,剩下的步骤都是没有操作到内存的,所以说stop或者destroy的回调方法调用的时候只是一个状态的变化,而没有真正意义的对内存进行实质性的停止或者销毁.但是会调用trimApplications方法来进一步操作.

ActivityManagerService.trimApplications

final void trimApplications() {synchronized (this) {int i;首先删除mRemoveProcess列表中包含的进程.这里一般包含的是crash后的进程,弹出ANR的进程,调用KillBackGroundProgress()方法杀死的进程.也就是说crash或者弹出Anr对话框我们点确定的时候系统并不会立马就将这些进程杀死,而是要等空闲时调用activityIdleInternalLocked方法时才会真正的来杀死.for (i=mRemovedProcesses.size()-1; i>=0; i--) {final ProcessRecord app = mRemovedProcesses.get(i);if (app.activities.size() == 0&& app.curReceiver == null && app.services.size() == 0) {if (app.pid > 0 && app.pid != MY_PID) {不杀死当前进程app.kill("empty", false);} else {try {app.thread.scheduleExit();} catch (Exception e) {// Ignore exceptions.}}cleanUpApplicationRecordLocked(app, false, true, -1);
将杀死的进程,移除mRemovedProcesses.remove(i);if (app.persistent) {addAppLocked(app.info, false, null /* ABI override */);}}}// Now update the oom adj for all processes.
告诉OOM Killer所有进程的优先级updateOomAdjLocked();}}

通过上面的源码知道,我们调用finish方法时关闭一个acitiviy的时候并不会真正的在内存中销毁它,而只是会调用onDestroy方法而已.除了会杀死mRemoveProcess列表中的进程,另外也就只会告诉OOM Killer所有进程的优先级.并不会主动的去杀死其他进程.

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



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

相关文章

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实

python中Hash使用场景分析

《python中Hash使用场景分析》Python的hash()函数用于获取对象哈希值,常用于字典和集合,不可变类型可哈希,可变类型不可,常见算法包括除法、乘法、平方取中和随机数哈希,各有优缺点,需根... 目录python中的 Hash除法哈希算法乘法哈希算法平方取中法随机数哈希算法小结在Python中,

Java Stream的distinct去重原理分析

《JavaStream的distinct去重原理分析》Javastream中的distinct方法用于去除流中的重复元素,它返回一个包含过滤后唯一元素的新流,该方法会根据元素的hashcode和eq... 目录一、distinct 的基础用法与核心特性二、distinct 的底层实现原理1. 顺序流中的去重

Spring @Scheduled注解及工作原理

《Spring@Scheduled注解及工作原理》Spring的@Scheduled注解用于标记定时任务,无需额外库,需配置@EnableScheduling,设置fixedRate、fixedDe... 目录1.@Scheduled注解定义2.配置 @Scheduled2.1 开启定时任务支持2.2 创建

关于MyISAM和InnoDB对比分析

《关于MyISAM和InnoDB对比分析》:本文主要介绍关于MyISAM和InnoDB对比分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录开篇:从交通规则看存储引擎选择理解存储引擎的基本概念技术原理对比1. 事务支持:ACID的守护者2. 锁机制:并发控制的艺

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可