Android AMS启动详解
作者:kailaisi 发布时间:2023-08-26 16:13:52
目录
启动
startService
AMS的创建
start()
setSystemProcess
后续
goingCallBack
startHomeOnAllDisplays
总结:
启动
在Android系统启动流程中中我们提到过,AMS是在system_service中启动的,
//frameworks/base/services/java/corri/android/server/SystemServer.java
//该方法主要启动服务 ActivityManagerService,PowerManagerService,LightsService,DisplayManagerService,PackageManagerService,UserManagerService。
//设置 ActivityManagerService,启动传感器服务。
startBootstrapServices(); // 启动引导服务
//该方法主要
//启动服务 BatteryService 用于统计电池电量,需要 LightService。
//启动服务 UsageStatsService,用于统计应用使用情况。
//启动服务 WebViewUpdateService。
startCoreServices(); // 启动核心服务
//该方法主要启动服务 InputManagerService,WindowManagerService。
//等待 ServiceManager,SurfaceFlinger启动完成,然后显示启动界面。
//启动服务 StatusBarManagerService,
//准备好 window, power, package, display 服务:
//- WindowManagerService.systemReady()
//- PowerManagerService.systemReady()
//- PackageManagerService.systemReady()
//- DisplayManagerService.systemReady()
startOtherServices(); // 启动其他服务
在启动核心服务功能中,会进行AMS的启动。
//frameworks/base/services/java/corri/android/server/SystemServer.java
private void startBootstrapServices() {
...
//这里会将ATMS注册到ServiceManager中,然后调用ATMS的start方法。
ActivityTaskManagerService atm = mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService();
//重点方法1。 注册AMS服务,并返回对应的对象信息
mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm);
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
//设置app安装器
mActivityManagerService.setInstaller(installer);
...
//重点方法2。 向ServiceManager中注册Binder服务
mActivityManagerService.setSystemProcess();
}
这里我们只截取了AMS的启动代码。
这里会通过startService方法来进行AMS的注册和启动过程。我们看一下具体的ActivityManagerService中的startService方法
startService
//
public static ActivityManagerService startService(SystemServiceManager ssm, ActivityTaskManagerService atm) {
sAtm = atm;
//调用SM的startService方法。创建AMS实例,并启动AMS
return ssm.startService(ActivityManagerService.Lifecycle.class).getService();
}
我们在ServiceManager的工作原理中讲解过,systemServiceManager.startService方法会将对应的服务注册到ServiceManager中,然后再调用start方法。
//frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public SystemService startService(String className) {
final Class<SystemService> serviceClass;
serviceClass = (Class<SystemService>)Class.forName(className);
return startService(serviceClass);
}
@SuppressWarnings("unchecked")
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();
final T service;
try {
//反射构造函数
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
//创建服务
service = constructor.newInstance(mContext);
...
//启动服务
startService(service);
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
public void startService(@NonNull final SystemService service) {
// Register it.
//注册到ServiceManager列表中
mServices.add(service);
//调用服务对应的onStart方法
service.onStart();
}
在启动AMS的时候传入的参数是:ActivityManagerService.Lifecycle.class。所以这里实际上会调用ActivityManagerService.Lifecycle 的构造方法,然后调用它的onStart方法
public static final class Lifecycle extends SystemService {
private final ActivityTaskManagerService mService;
public Lifecycle(Context context) {
super(context);
//创建AMS对象
mService = new ActivityManagerService(context, sAtm);
}
@Override
public void onStart() {
//调用AMS的start方法
mService.start();
}
public ActivityManagerService getService() {
//返回了AMS实例
return mService;
}
}
在Lifecycle对象的创建过程中,会创建AMS对象,然后通过start()方法进行了启动。
AMS的创建
对于AMS对象的创建是通过构造函数来创建的。
//构造方法,
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
//获取系统的ActivityThread
mSystemThread = ActivityThread.currentActivityThread();
//创建一个ServiceThread用来处理AMS接收到的命令
mHandlerThread = new ServiceThread(TAG,THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
mUiHandler = mInjector.getUiHandler(this);
//低内存监控
mLowMemDetector = new LowMemDetector(this);
//初始化广播队列。这里包含了前台广播,后台广播等
mFgBroadcastQueue = new BroadcastQueue(this, mHandler, "foreground", foreConstants, false);
mBgBroadcastQueue = new BroadcastQueue(this, mHandler, "background", backConstants, true);
mOffloadBroadcastQueue = new BroadcastQueue(this, mHandler, "offload", offloadConstants, true);
mBroadcastQueues[0] = mFgBroadcastQueue;
mBroadcastQueues[1] = mBgBroadcastQueue;
mBroadcastQueues[2] = mOffloadBroadcastQueue;
//用于保存注册的Service
mServices = new ActiveServices(this);
//map,用于保存注册的ContentProvider
mProviderMap = new ProviderMap(this);
mPackageWatchdog = PackageWatchdog.getInstance(mUiContext);
mAppErrors = new AppErrors(mUiContext, this, mPackageWatchdog);
//创建 /data/system目录
final File systemDir = SystemServiceManager.ensureSystemDir();
//创建进程统计服务,保存在/data/system/proccstats目录中。
mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
//赋值ATM,并进行初始化
mActivityTaskManager = atm;
mActivityTaskManager.initialize(mIntentFirewall, mPendingIntentController, DisplayThread.get().getLooper());
//CPU * 进程
mProcessCpuThread = new Thread("CpuTracker") {
@Override
public void run() {
...
}
};
}
在AMS的构造函数中进行了一些初始化的东西:比如说启动CPU监控、启动进程统计服务、启动低内存监控、初始化Service和ContentProvider对应的保存类等等。
start()
当AMS类创建完成之后,会调用start()方法。
private void start() {
//移除所有的进程组
removeAllProcessGroups();
//启动CpuTracker线程
mProcessCpuThread.start();
//启动电池统计服务,能够统计具体的应用的电池消耗,从而来进行一定的电量统计
mBatteryStatsService.publish();
//创建LocalService,并添加到LocalServices列表中
LocalServices.addService(ActivityManagerInternal.class, new LocalService());
mActivityTaskManager.onActivityManagerInternalAdded();
mUgmInternal.onActivityManagerInternalAdded();
mPendingIntentController.onActivityManagerInternalAdded();
}
在start方法中,会将在构造函数中创建的一些线程进行启动。
setSystemProcess
在创建并启动完成之后,会通过setSystemProcess方法来向ServiceManager中注册一些系统相关的服务。
public void setSystemProcess() {
try {
//注册ActivityService服务
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
//注册进程状态服务
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
//注册内存Binder
ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,DUMP_FLAG_PRIORITY_HIGH);
//注册图像Binder
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
//注册SQLite DB binder
ServiceManager.addService("dbinfo", new DbBinder(this));
if (MONITOR_CPU_USAGE) {
//注册CPU使用情况的Binder
ServiceManager.addService("cpuinfo", new CpuBinder(this),/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
}
//注册权限控制Binder
ServiceManager.addService("permission", new PermissionController(this));
//注册进程管理Binder
ServiceManager.addService("processinfo", new ProcessInfoService(this));
//获取“android”应用的ApplicationInfo,并装载到mSystemThread
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo("android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
//创建ProcessRecord维护进程的相关信息
synchronized (this) {
ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,...);
app.setPersistent(true);
app.pid = MY_PID;
app.getWindowProcessController().setPid(MY_PID);
app.maxAdj = ProcessList.SYSTEM_ADJ;
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
mPidsSelfLocked.put(app);
mProcessList.updateLruProcessLocked(app, false, null);
updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find android system package", e);
}
}
在这个方法中会设置一些系统进程,主要功能为:
注册一些服务:activity、procstats、meminfo、gfxinfo、dbinfo、cpuinfo、permission、processinfo等。
获取包名为“android”的应用的ApplicationInfo对象,并将该ApplicationInfo信息安装设置到SystemThread(系统进程主线程)。即可以理解,系统也是一个特殊的应用。
创建ProcessRecord维护进程的相关信息,这里MY_PID即为SystemServer进程ID。
启动 检测应用运行和交互。
后续
当AMS创建并启动之后,会有一系列的后续的工作需要处理。这些操作都是在**startOtherServices()**中去调用的
private void startOtherServices() {
//注册系统的ContentProvider信息
mActivityManagerService.installSystemProviders();
mActivityManagerService.setWindowManager(wm);
mActivityManagerService.systemReady(() -> {
......//goingCallback
}, BOOT_TIMINGS_TRACE_LOG);
}
这里的主要功能是:
关键服务继续进行初始化
已经启动的进程,如果没有FLAG_PERSISTENT标志位,则会被kill掉
运行goingCallBack
启动launcher的Activity,即桌面应用。
这里继续跟踪一下goingCallBack的具体执行内容。
goingCallBack
mActivityManagerService.systemReady(() -> {
try {
//启动NativeCrash的监测
mActivityManagerService.startObservingNativeCrashes();
} catch (Throwable e) {
reportWtf("observing native crashes", e);
}
if (!mOnlyCore && mWebViewUpdateService != null) {
webviewPrep = SystemServerInitThreadPool.get().submit(() -> {
//启动WebView相关
mWebViewUpdateService.prepareWebViewInSystemServer();
}, WEBVIEW_PREPARATION);
}
try {
//启动systemUI
startSystemUi(context, windowManagerF);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
...
}
在这个里面会继续进行一些初始化的工作:
启动NativeCrash监测
启动WebView相关服务
启动SystemUI
startHomeOnAllDisplays
该功能主要是进行桌面程序的启动,和AMS的启动流程关联不大,在这里不再详细进行解析。
总结:
AMS是在SystemServer进程中进行创建并启动的
在AMS的服务启动过程中,通过构造函数进行了一些对象的创建和初始化工作(初Activity外其他3大组件的列表和调度对象的创建;内存、电池、权限、CPU等的监控等等相关对象的创建),并且通过start()方法启动服务(移除进程组、启动CPU线程、权限注册、电池服务等等)。
AMS创建并将对应服务启动之后,会通过setSystemProcess方法,将framework-res.apk的信息加入到SystemServer进程的LoadedApk中,并创建了SystemServer进程的ProcessRecord,加入到了mPidsSelfLocked,交给AMS来统一管理
AMS启动之后的后续工作,主要调用systemReady()和传入的goingCallBack来执行。主要是各种服务或者进程,等AMS启动完成后需要进一步完成的工作以及系统相关的初始化。
桌面应用是在systemReady()方法中启动,systemUI是在goingCallback中完成。
当桌面应用启动完成以后,发送开机广播ACTION_BOOT_COMPLETED。
来源:https://juejin.cn/post/6944971739009024007


猜你喜欢
- 本文实例为大家分享了java文件处理工具类的具体代码,供大家参考,具体内容如下import java.io.BufferedInputStr
- 下面由我来给大家展示用spring aop实现 * 的例子(电脑打印)下面就看一下具体的代码:先定义一个打印机的接口package aop
- 说明:基于atguigu学习笔记。简介Webflux是 Spring5 添加新的模块,用于 web 开发的,功能和 SpringMVC 类似
- 一、在GitHub上创建一个OAuth二、OAuth的原理Spring官方文档三、OkHttp的使用OkHttp官方网站1.Post代码示例
- 本文实例讲述了Android自定义个性化的Dialog。分享给大家供大家参考,具体如下:Dialog:mDialog = new Dialo
- 概述从今天开始, 小白我将带大家开启 Jave 数据结构 & 算法的新篇章.循环队列循环队列 (Circular Queue) 是一
- 实例如下所示:private static String savefile = "E:\\test.txt";priva
- 一、什么是 RestTemplate?RestTemplate是执行HTTP请求的同步阻塞式的客户端,它在HTTP客户端库(例如JDK Ht
- 1. 前言ResultSetMetaData 叫元数据,是数据库 列对象,以列为单位封装为对象。元数据,指的是其包含列名,列值,列类型,列长
- 前言接触Android Stuidio有一阵子了,之前用的时候有很多小问题,不过现在的版本感觉已经很好用了,所以准备彻底从Eclipse转战
- 项目中很多时候需要读取自定义配置文件,本地开发工具怎么写都成功但是部署到服务其上就出现问题,异常BOOT-INF/classes!/conf
- 业务场景我们知道在使用PageHelper分页插件时,会对执行PageHelper.startPage(pageNum, pageSize)
- springboot整合MySQL很简单,多数据源就master,slave就行了,但是在整合DB2就需要另起一行,以下是同一个yml文件先
- 这篇文章主要介绍了spring如何实现两个xml配置文件间的互调,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值
- 本文实例为大家分享了C#强制转换和尝试转换的方法,供大家参考,具体内容如下将String[]类型的Object类型,转换为String[]类
- substring(参数)是java截取字符串的一个方法。它有两种传参的方式:第一种:public String substring(int
- 先看看效果图:实现思路:监听ListView的滑动,等目的项为列表第一个可见的ItemView时,添加一个一个的布局,产生悬停效果实现代码:
- 目录简单介绍具体实现首先,咱们先配置一下相关的jar包(pom.xml)创建一个Pet接口,存放方法say()创建一个Person类创建一个
- 当我们需要制作动态炫酷科技感很强的UI时,美术一般会给我们提供一些序列图,这时候我们只需在程序里实现序列动画。一.动画机unity自带的帧动
- 假如我们有一张banner_item表,现需要通过banner_id查出所有数据(查询List)@Datapublic class Bann