com.android.server.am.ActivityManagerService
本文在 API 27 基础上展开分析。
文章篇幅的长度与附上的代码量有关,请耐心查看。
没时间的小伙伴,可以先大概浏览,有一个感性认识,后续再进行研究。
本文也是参考学习,如有错误,欢迎指正~
本文分析AMS启动过程的主要流程,并非全部。
有针对性和选择性的分析AMS的相关代码,非AMS的暂不讨论。
为防止深入代码导致记忆混乱,采用 step
标识跟进,例如 step 1
,step 1.1
,step 1.1.1
标识从某个方法入口依次跟进。
摘要
AMS - ActivityManagerService ,是 Android 最核心 的服务,主要负责系统中 四大组件 的启动、切换、调度及应用程序的管理和调度等工作。
AMS通信结构如下图所示:
AMS通信关键词
- AMS:ActivityManagerService ;PMS-PackageManagerService;
- 系统服务;普通应用;Client / Service 思想;
- Application;ApplicationInfo;
- SystemServiceManager;ServiceManager;LocalServices;
AMS启动过程
为使读者对AMS启动有明确的方向,先将大致流程抛出来,方便整体把控。
- 创建出
SystemServer
进程的 Android 运行环境 -
AMS
的初始化和启动 - 将
SystemServer
进程纳入到AMS
的管理体系 -
AMS
启动完成的后续工作
前提 已知
Zygote
创建fork
出的第一个 java 进程是SystemServer
。- 每个进程的入口是
main
函数。
com.android.internal.os.Zygote
public static void main(String argv[]) {
...
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
...
}
整个过程从 SystemServer
进程的入口开始分析,涉及 AMS
启动主要过程的伪代码如下:
com.android.server.SystemServer
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
try {
...
// Initialize native services.
System.loadLibrary("android_servers");
...
// Initialize the system context.
// systemServer在启动任何服务之前,先调用了createSystemContext 创建出 mSystemContext
// step 1
createSystemContext();
// Create the system service manager.
// SystemServiceManager 负责启动所有的 系统服务
// mSystemContext 构造出 SystemServiceManager,
mSystemServiceManager = new SystemServiceManager(mSystemContext);
...
// LocalServices 管理当前进程的服务
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
...
} finally {
....
}
// Start services.
try {
...
// step 2 启动引导服务,在其中创建并启动AMS
startBootstrapServices();
...
// step 3 启动其他服务,在其中AMS注册了SettingsProvider和其他后续工作
startOtherServices();
...
} catch (Throwable ex) {
...
} finally {
...
}
...
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
Step 1 createSystemContext()
创建出 SystemServer
进程的 Android 运行环境
com.android.server.SystemServer
private void createSystemContext() {
// step 1.1 调用ActivityThread的systemMain函数,其中会创建出系统对应的Context对象
ActivityThread activityThread = ActivityThread.systemMain();
// step 1.2 取出上面函数创建的Context对象,保存在mSystemContext中
mSystemContext = activityThread.getSystemContext();
// 设置系统主题
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
...
}
Step 1.1 ActivityThread.systemMain()
调用 ActivityThread
的 systemMain()
函数,其中会创建出系统对应的 Context
对象
android.app.ActivityThread
public static ActivityThread systemMain() {
//虽然写着ActivityManager,但和AMS没有任何关系,就是利用系统属性和配置信息进行判断
if (!ActivityManager.isHighEndGfx()) {
//低版本关闭硬件渲染功能
ThreadedRenderer.disable(true);
} else {
ThreadedRenderer.enableForegroundTrimming();
}
// step 1.1.1 创建ActivityThread
ActivityThread thread = new ActivityThread();
//step 1.1.2 调用attach函数,参数为true
thread.attach(true);
return thread;
}
ActivityThread
有自己的 main
入口函数,明确此处调用的是 systemMain()
。
ActivityThread#systemMain() 了解到主要功能有:
- 判断是否开启硬件加速。
- 创建
ActivityThread
对象。 - 调用 thread 对象的
attach(true)
,注意参数 system 传入** true**。
Step 1.1.1 ActivityThread thread = new ActivityThread();
ActivityThread 的构造函数比较简单
com.android.app.ActivityThread
ActivityThread() {
mResourcesManager = ResourcesManager.getInstance();
}
比较关键的是它内部的成员变量,
com.android.app.ActivityThread
public final class ActivityThread {
...
//定义了AMS与应用通信的接口
final ApplicationThread mAppThread = new ApplicationThread();
//拥有自己的looper,说明ActivityThread确实可以代表事件处理线程
final Looper mLooper = Looper.myLooper();
//H继承Handler,ActivityThread中大量事件处理依赖此Handler
final H mH = new H();
//用于保存该进程的ActivityRecord
final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>()
...
//用于保存进程中的Service
final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
...
//用于保存进程中的Application
final ArrayList<Application> mAllApplications = new ArrayList<Application>();
...
}
ActivityThread
,是 Android Framework 中一个非常重要的类,它代表应用进程的主线程,其职责是调度及执行在该线程中运行的四大组件。
在Android中
应用进程,指那些运行Apk的进程,它们有Zygote fork出来,其中运行着独立的dalvik虚拟机。
系统进程,也应用进程相对,例如 Zygote 和 SystemServer。其中SystemServer 也是由Zygote fork出来的,也运行着一些系统Apk,例如framework-res.apk
、SettingsProvider.apk
等,该进程也创建了主线程ActivityThread,所以SystemServer也可以看做是特殊的应用进程
对于上面提到的ActivityThread的成员变量,其用途基本上可以从名称中得知,这里仅说明一下ApplicationThread。
AMS负责 进管理 和 进程调度,因此 AMS 和应用进程之间通信需要 Binder机制。为此 Android 提供了一个 android.app.IApplicationThread 接口,继承 IInterface,该接口定义了 AMS 和应用进程之间的交互函数。例如:scheduleLaunchActivity
、scheduleCreateService
等
当 AMS 与应用进程通信时,ApplicationThread 继承 IApplicationThread.Stub 作为Binder通信的服务端。
step 1.1.2 thread.attach(true);
android.app.ActivityThread
//此时,我们传入的参数为true,表示该ActivityThread是**系统进程的ActivityThread**
private void attach(boolean system) {
//创建出的ActivityThread保存在类的静态变量sCurrentActivityThread
//AMS中的大量操作将会依赖于这个ActivityThread
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
// '应用进程' 的处理流程
...
} else {
// '系统进程' 的处理流程,该情况只在SystemServer中处理
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
//设置DDMS(Dalvik Debug Monitor Service)中看到的SystemServer进程的名称为“system_process”
android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId());
try {
// 创建ActivityThread中的重要成员:
// Instrumentation、Application、Context
// step 1.1.2.1
mInstrumentation = new Instrumentation();
// step 1.1.2.3
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo); // step 1.1.2.2
// step 1.1.2.4
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
...
}
}
//以下系统进程和非系统进程均会执行
...
//注册Configuration变化的回调通知
ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
//当系统配置发生变化时(例如系统语言发生变化),回调该接口
...
}
...
});
}
系统进程在ActivityThread的attach函数的主要工作:
- 创建Instrumentation
- 创建Context
Context是Android中的一个抽象类,用于维护应用运行环境的全局信息。
通过Context可以访问应用的资源和类,甚至进行系统级的操作,例如启动Activity、发送广播等。 - 创建Application
step 1.1.2.1 new Instrumentation()
Instrumentation是Android中的一个工具类,当该类被启动时,它将优先于其它的类被初始化。
此时,系统先创建它,再通过它创建其它组件。
此外,系统和应用组件之间的交互也将通过Instrumentation来传递。
因此,Instrumentation就能监控系统和组件的交互情况了。
实际使用时,可以创建该类的派生类进行相应的操作。
这个类在介绍启动Activity的过程时还会碰到,此处不作展开。
step 1.1.2.2 getSystemContext()
android.app.ActivityThread
public ContextImpl getSystemContext() {
synchronized (this) {
if (mSystemContext == null) {
//调用ContextImpl的静态函数createSystemContext
// step 1.1.2.2.1
mSystemContext = ContextImpl.createSystemContext(this);
}
return mSystemContext;
}
}
step 1.1.2.2.1 ContextImpl.createSystemContext
android.app.ContextImpl
static ContextImpl createSystemContext(ActivityThread mainThread) {
// 创建LoadedApk类,代表一个加载到系统中的APK
// 注意现在处于构建Android运行环境阶段,PMS服务还没有启动,无法得到有效的Application,后续PMS启动后,后调用 LoadedApk.installSystemApplicationInfo 进行填充
// 此时实例化的LoadedApk只是一个空壳,内部使用空的Application
// step 1.1.2.2.1.1
LoadedApk packageInfo = new LoadedApk(mainThread);
//调用ContextImpl的构造函数,参数中传入了上面生成的对象packageInfo
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
null);
// 初始化资源
context.setResources(packageInfo.getResources());
context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
context.mResourcesManager.getDisplayMetrics());
return context;
}
createSystemContext的主要工作:
- 创建一个 LoadApk,代表一个加载到系统中的Apk
- 将传入的线程参数 mainThread 和 上一步生成的packageInfo 实例化一个ContextImpl对象
似乎没有什么特别的,那么为什么函数名叫做 createSystemContext ??
为了回答这个问题,就要看看LoadedApk的构造函数
step 1.1.2.2.1.1
android.app.LoadApk
LoadedApk(ActivityThread activityThread) {
mActivityThread = activityThread;
mApplicationInfo = new ApplicationInfo();
//packageName为"android"
mApplicationInfo.packageName = "android";
mPackageName = "android";
//下面许多参数为null
...
}
注意到 mPackageName = "android",也就是 framework-res.apk。该Apk仅供SystemServer进程使用,因此上一步的方法名被定义成 createSystemContext。
又注意到,实例化了一个mApplicationInfo对象,但是只赋值了其中的packageName属性,所以说现在的LoadedApk只是一个空壳。ApplicationInfo中包含了许多Apk重要信息,当之后的PMS启动,完成对应的解析后,AMS将重新调用 LoadedApk.installSystemApplicationInfo 进行填充。
step 1.1.2.3 ContextImpl.createAppContext
android.app.ContextImpl
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
null);
context.setResources(packageInfo.getResources());
return context;
}
createAppContext的工作比较简单,利用 ActivityThread 和 LoadApk 构造出 ContextImpl。
ContextImpl的构造函数主要是完成了一些变量的初始化,建立起 ContextImpl 与 ActivityThread、LoadApk、ContentResolver 之间的关系。
以后可以从 ContextImpl中 获取一些变量。
注意 createAppContext 和 上一步的 createSystemContext 中构造 ContextImpl是一样的
代码简单,不再展开,注意在函数的最后建立和 ContentResolver 之间的联系
mContentResolver = new ApplicationContentResolver(this, mainThread, user);
step 1.1.2.4 context.mPackageInfo.makeApplication
先来看一下 Application 关系图
Application 关系图Android中Application类用于保存应用的全局状态
Activity和Service都和具体的Application绑定在一起,通过继承关系可知,每个Activity和Service均加入到Android运行环境中。
android.app.ActivityThread
private void attach(boolean system) {
...
// mPackageInfo是LoadApk类型,从context中获取LoadApk,然后调用LoadApk的makeApplication函数
// step 1.1.2.4
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
// 调用Application的onCreate方法
mInitialApplication.onCreate();
...
}
android.app.LoadedApk
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
...
Application app = null;
String appClass = mApplicationInfo.className;
// 此流程 forceDefaultAppClass == true
if (forceDefaultAppClass || (appClass == null)) {
// 系统进程中,对应下面的appClass
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
initializeJavaContextClassLoader();
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
//实际上最后通过反射创建出Application
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
...
}
//一个进程支持多个Application,mAllApplications用于保存该进程中的Application对象
mActivityThread.mAllApplications.add(app);
mApplication = app;
// 此流程 instrumentation == null
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
...
}
}
// Rewrite the R 'constants' for all library apks.
...
return app;
}
makeApplication 的主要工作:
- 创建 framework-res.apk 对应的Application
- 调用Application的onCreate函数
总结 createSystemContext
至此,createSystemContext函数介绍完毕。
当 SystemServer 调用 createSystemContext 完毕后:
- 得到一个 ActivityThread 对象,它代表当前进程(系统进程)的主线程
- 得到一个 Context,对于 SystemServer 而言,它包含 Application 运行环境 和 framework-res.apk(名为"android"的LoadedAPK) 有关。
思考
Q:为什么启动所有的服务前,SystemServer先要调用createSystemContext?
A:众所周知,Android是以Java为基础的,Java运行在进程中。
但是,Android想努力构筑一个自己的运行环境,组件的运行和它们之间的交互均在该环境中实现。
createSystemContext
函数就是为* SystemServer系统进程* 搭建一个和 普通应用进程 一样的 Android环境。
Android运行环境,是在进程的基础上构建的,但是把 进程的概念被模糊化,所以应用程序一般只和Android运行环境交互。
基于同样的道理,Android 希望 SystemServer进程内部运行的应用,也通过Android运行环境交互,因此才调用了 createSystemContext 函数。
创建Android运行环境时,
由于SystemServer的特殊性,SystemServer.main() 调用了 ActivityThread.systemMain() 函数
对于普通的应用程序,将在自己的主线程汇中调用 ActivityThread.main() 函数
进程 的 Android运行环境 涉及的主要类之间的关系如下图,其中核心类是ContextImpl ,通过它可以得到 ContentResolver、系统资源Resources、应用信息Application、当前进程的主线程ActivityThread、Apk信息LoadedApk等。
Android 运行环境涉及的主要类之前的关系Step 2 AMS初始化
Step 1 创建完Android运行环境和创建系统服务管理后,创建了SystemServiceManager,并将其加入到了 LocalServices 中。
com.android.server.SystemServer
private void run() {
// Step 1
createSystemContext();
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
...
// Step 2
startBootstrapServices();
}
之后,SystemServer
就调用了 startBootstrapServices
正式进入AMS的创建和启动过程。
伪代码如下:
com.android.server.SystemServer
private void startBootstrapServices() {
Installer installer = mSystemServiceManager.startService(Installer.class);
...
// Activity manager runs the show.
// 启动AMS,然后获取AMS保存到变量中
// Step 2.1
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
//以下均是将变量存储到AMS中
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
...
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mPackageManager = mSystemContext.getPackageManager();
...
// Set up the Application instance for the system process and get started.
// Step 2.2
mActivityManagerService.setSystemProcess();
...
mPackageManagerService.systemReady();
...
mActivityManagerService.systemReady(()->{ ... });
...
}
注意上面代码 mSystemServiceManager 并没有直接启动 AMS ,而是启动 AMS 的内部类ActivityManagerService.Lifecycle
.
由于 AMS 并没有继承 SystemService
,因此不能通过 SystemServiceManager.startService()
直接启动(内部实现采用反射的方式),例如可以直接启动Installer
。
AMS 的内部类 Lifecycle
继承 SystemService
,像一个适配器来间接操作 AMS。让 AMS 能够 像 SystemService
一样被 SystemServiceManager
通过反射的方式启动。
Lifecycle类简单如下:
com.android.server.am.ActivityManagerService
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;
public Lifecycle(Context context) {
super(context);
// step 2.1.1 调用AMS的构造函数
mService = new ActivityManagerService(context);
}
@Override
public void onStart() {
// step 2.1.2 调用AMS的start函数
mService.start();
}
@Override
public void onCleanupUser(int userId) {
mService.mBatteryStatsService.onCleanupUser(userId);
}
public ActivityManagerService getService() {
return mService;
}
}
Step 2.1.1 AMS 构造函数
构造函数较长但简单,主要初始化了一些变量,可以过一遍
public ActivityManagerService(Context systemContext) {
//AMS的运行上下文与SystemServer一致
mContext = systemContext;
............
//取出的是ActivityThread的静态变量sCurrentActivityThread
//这意味着mSystemThread与SystemServer中的ActivityThread一致
mSystemThread = ActivityThread.currentActivityThread();
............
mHandlerThread = new ServiceThread(TAG,
android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
//处理AMS中消息的主力
mHandler = new MainHandler(mHandlerThread.getLooper());
//UiHandler对应于Android中的UiThread
mUiHandler = new UiHandler();
if (sKillHandler == null) {
sKillThread = new ServiceThread(TAG + ":kill",
android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
sKillThread.start();
//用于接收消息,杀死进程
sKillHandler = new KillHandler(sKillThread.getLooper());
}
//创建两个BroadcastQueue,前台的超时时间为10s,后台的超时时间为60s
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;
//创建变量,用于存储信息
mServices = new ActiveServices(this);
mProviderMap = new ProviderMap(this);
mAppErrors = new AppErrors(mContext, this);
//这一部分,分析BatteryStatsService时提过,进行BSS的初始化
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);
//创建ProcessStatsService,感觉用于记录进程运行时的统计信息,例如内存使用情况,写入/proc/stat文件
mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
//启动Android的权限检查服务,并注册对应的回调接口
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);
}
}
}
});
//用于定义ContentProvider访问指定Uri对应数据的权限,aosp中似乎没有这文件
mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
//创建多用户管理器
mUserController = new UserController(this);
//获取OpenGL版本
GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
............
//资源配置信息置为默认值
mConfiguration.setToDefaults();
mConfiguration.setLocales(LocaleList.getDefault());
mConfigurationSeq = mConfiguration.seq = 1;
//感觉用于记录进程的CPU使用情况
mProcessCpuTracker.init();
//解析/data/system/packages-compat.xml文件,该文件用于存储那些需要考虑屏幕尺寸的APK的一些信息
//当APK所运行的设备不满足要求时,AMS会根据xml设置的参数以采用屏幕兼容的方式运行该APK
mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
//用于根据规则过滤一些Intent
mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
//以下的类,似乎用于管理和监控AMS维护的Activity Task信息
//ActivityStackSupervisor是AMS中用来管理Activity启动和调度的核心类
mStackSupervisor = new ActivityStackSupervisor(this);
mActivityStarter = new ActivityStarter(this, mStackSupervisor);
mRecentTasks = new RecentTasks(this, mStackSupervisor);
//创建线程用于统计进程的CPU使用情况
mProcessCpuThread = new Thread("CpuTracker") {
@Override
public void run() {
while (true) {
try {
try {
//计算更新信息的等待间隔
//同时利用wait等待计算出的间隔时间
......
} catch(InterruptedException e) {
}
//更新CPU运行统计信息
updateCpuStatsNow();
} catch (Exception e) {
..........
}
}
}
};
//加入Watchdog的监控
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
}
Step 2.1.2 AMS 的 start 函数
private void start() {
//完成统计前的复位工作
Process.removeAllProcessGroups();
//开始监控进程的CPU使用情况
mProcessCpuThread.start();
//注册电池状态服务
mBatteryStatsService.publish(mContext);
//注册一些应用信息和控制的服务,比如权限等
mAppOpsService.publish(mContext);
// ActivityManagerInternal 是 activity manager 本地管理服务的接口
LocalServices.addService(ActivityManagerInternal.class, new LocalService());
}
start() 函数的主要工作:
- 启动CPU监控线程,该线程将会开始统计不同进程使用CPU的情况
- 发布一些服务,如BatteryStatsService、AppOpsService(权限管理相关)和本地实现的LocalService继承ActivityManagerInternal的服务
至此,AMS 初始化完成
下一步将 SystemServer 纳入AMS的管理体系
step 2.2 AMS#setSystemProcess
public void setSystemProcess() {
try {
// step 2.2.1 以下几个向ServiceManager注册几个服务
// AMS自己,在这里注册,以后通过ServiceManager获取,最常见的获取key为"activity"的服务
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
//注册进程统计信息的服务
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默认为true
if (MONITOR_CPU_USAGE) {
//用于输出进程的CPU使用情况
ServiceManager.addService("cpuinfo", new CpuBinder(this));
}
//注册权限管理服务
ServiceManager.addService("permission", new PermissionController(this));
//注册获取进程信息的服务
ServiceManager.addService("processinfo", new ProcessInfoService(this));
// step 2.2.2 通过 PMS 查询 package 名为 "android" 的应用的ApplicationInfo,即系统应用
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
// step 2.2.3 通过查询的结果进行安装
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
// step 2.2.4 以下与AMS的进程管理
synchronized (this) {
ProcessRecord 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);
}
}
AMS的setSystemProcess有四个主要功能:
- 向
ServiceManager
注册服务统一管理,如 AMS 本身。 - 获取
package
名为 "android" 的应用的ApplicationInfo
,即系统应用framework-res.apk
。 - 调用
ActivityThread
的installSystemApplicationInfo
,回忆之前创建的LoadedApk
是一个空壳,没有实际的ApplicationInfo
。 - AMS 进程管理相关的操作
step 2.2.1 注册服务 ServiceManager.addService()
com.android.server.am.ActivityManagerService # setSystemProcess()
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
注意平时常用的 AMS 获取,要知道是在这里进行 添加 的。
Step 2.2.2 获取系统应用信息 getApplicationInfo
com.android.server.am.ActivityManagerService
public void setSystemProcess() {
ApplicationInfo info = mContext.getPackageManager() // Step 2.2.2.1
.getApplicationInfo( "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY); // Step 2.2.2.2
}
Step 2.2.2.1 mContext.getPackageManager()
Context 的实现类是 ContextImpl
android.app.ContextImpl
public PackageManager getPackageManager() {
if (mPackageManager != null) {
return mPackageManager;
}
// 依赖于ActivityThread,此时为系统进程的主线程,调用ActivityThread的getPackageManager()函数
IPackageManager pm = ActivityThread.getPackageManager();
if (pm != null) {
// Doesn't matter if we make more than one instance.
// 利用PMS的代理对象,构建ApplicationPackageManager对象(继承PackageManager)
// Note:PackageManager不继承IPackageManager。IPackageManager继承IInterface,属于Binder接口
return (mPackageManager = new ApplicationPackageManager(this, pm));
}
return null;
}
跟进一下ActivityThread的getPackageManager:
android.app.ActivityThread
public static IPackageManager getPackageManager() {
if (sPackageManager != null) {
return sPackageManager;
}
// 依赖于Binder通信,并通过ServiceManager获取到PMS对应的BpBinder
IBinder b = ServiceManager.getService("package");
//得到PMS对应的Binder服务代理
sPackageManager = IPackageManager.Stub.asInterface(b);
return sPackageManager;
}
从上面我们可以看到,获取 PMS
用到了Binder通信。方式和获取 AMS
一样。
实际上,PMS
由 SystemServer
创建,与 AMS
运行在同一一个进程,且初始化比 AMS
早,但是比构建 Android 运行环境晚,所以之前构建的系统 LoadedApk
是一个空壳,实际内容需要从 PMS
中获取。
实际上,AMS
完全可以不经过 Context
、ActivityThread
、Binder
来获取 PMS
,直接在 SystemServer
中取 mPackageManagerService
属性即可
但是源码通过 ActivityThread.getPackageManager
等之前和之后一系列操作获取 PMS
的原因是:
让 SystemServer
进程中的服务,也通过之前构建的 Android 运行环境来交互,保证了组件之间交互接口的统一,为未来的系统保留了可扩展性。
step 2.2.2.2 通过 PMS 获取 getApplicationInfo()
得到 PMS
服务的代理对象后,AMS
调用 PMS
的getApplicationInfo
接口,获取 package
名为 "android" 的 ApplicationInfo
。
在 AMS
的 setSystemProcess
被调用前,PMS
已经启动了。
在 PMS
的构造函数中,它将解析手机中所有的AndroidManifest.xml
,然后形成各种数据结构以维护应用的信息。
getApplicationInfo
就是通过 package
名,从对应的数据结构中取出对应的应用信息。这部分内容主要就是查询数据结构的内容,不作深入分析。
2.2.3 installSystemApplicationInfo
在上一步得到 framework-res.apk
的 ApplicationInfo
后,需要将该 ApplicationInfo
保存到 SystemServer
对应的ActivityThread
中。
com.android.server.am.ActivityMagerService
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
AMS
中的 mSystemThread
就是 SystemServer
中创建出的 ActivityThread
。
跟进一下 ActivityThread
的 installSystemApplicationInfo
函数
com.android.app.ActivityThread
public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
synchronized (this) {
//调用SystemServer中创建出的ContextImpl的installSystemApplicationInfo函数
getSystemContext().installSystemApplicationInfo(info, classLoader);
getSystemUiContext().installSystemApplicationInfo(info, classLoader);
// give ourselves a default profiler
// 创建一个Profiler对象,用于性能统计
mProfiler = new Profiler();
}
}
继续跟进 ContextImpl
的 installSystemApplicationInfo
函数
com.android.app.ContextImpl
void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
// mPackageInfo 的类型为 LoadedApk
mPackageInfo.installSystemApplicationInfo(info, classLoader);
}
继续跟进 LoadedApk
的 installSystemApplicationInfo
函数
com.android.app.LoadedApk
/**
* Sets application info about the system package.
*/
void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
// 这个接口仅供系统进程调用,故这里断言了一下
assert info.packageName.equals("android");
mApplicationInfo = info;
mClassLoader = classLoader;
}
至此,我们知道了 installSystemApplicationInfo
的真相就是:
将包名为 "android" 对应的 ApplicationInfo
(framework-res.apk
),加入到之前创建的系统 LoadedApk
中(SystemServer#run#createSystemContext)
原因是:在此之前创建 SystemContext
时,PMS
还没有执行对手机中的文件进行解析的操作,因此初始化的 LoadApk
并没有持有有效的 ApplicationInfo
(仅实例化了一个空 ApplicationInfo
对象,设置了 packageName
属性为"android",其他并没有设置)。
在此基础上,AMS
下一步的工作就呼之欲出了
因为 AMS
是专门用于进程管理和调度的,但是framework.apk
运行在 SystemServer
进程中,所以SystemServer
进程也应该在 AMS
有对应的管理结构。(SystemServer
创建了 AMS
,但是 AMS
还想管理SystemServer
^ - ^ )
于是,AMS
的下一步工作就是将 SystemServer
的运行环境和一个进程管理结构对应起来,并进行统一的管理。
2.2.4 AMS进程的管理
ProcessRecord
该类定义一个进程的详细信息
mLruProcess列表保存进程
进程对应的oom_adj值将决定进程是否被kill掉
AMS#setSystemProcess函数中,进程管理相关的代码如下:
com.android.server.am.ActivityManagerServer
public void setSystemProcess() {
...
synchronized (this) {
// 创建进程管理对应的结构 ProcessRecord
ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
// 由于此时创建的是SystemServer进程对应的ProcessRecord,因此设置了一些特殊值
app.persistent = true;
app.pid = MY_PID;
app.maxAdj = ProcessList.SYSTEM_ADJ;
// 将SystemServer对应的ApplicationThread保存到ProcessRecord中
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
synchronized (mPidsSelfLocked) {
// 按pid将ProcessRecord保存到mPidsSelfLocked中
mPidsSelfLocked.put(app.pid, app);
}
// TODO 调整 mLruProcess 列表的位置,最近活动过的进程总是位于前列,同时拥有Activity的进程总是前于只有Service的进程
updateLruProcessLocked(app, false, null);
// TODO 更新进程对应的oom_adj值,oom_adj将决定进程是否被kill掉
updateOomAdjLocked();
}
...
}
这里我们仅分析一下创建进程管理结构的函数newProcessRecordLocked。
updateLruProcessLocked和updateOomAdjLocked函数比较复杂,等对AMS有更多的了解后,再做分析。
com.android.server.am.ActivityManagerServer
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);
//isolated此时为false
if (isolated) {
...
}
//创建出对应的存储结构
final 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中
//该变量的类型为ProcessMap<ProcessRecord>
//结合前面的代码,我们知道AMS有两种方式可以取到ProcessRecord,一是根据进程名,二是根据进程名称
addProcessNameLocked(r);
return r;
}
跟进一下 ProcessRecord
的构造函数
com.android.server.am.ProcessRecord
ProcessRecord(BatteryStatsImpl _batteryStats, ApplicationInfo _info,
String _processName, int _uid) {
mBatteryStats = _batteryStats; //用于电量统计
info = _info; //保存ApplicationInfo
...........
processName = _processName; //保存进程名
//一个进程能运行多个Package,pkgList用于保存package名
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();
}
总结
AMS#setSystemProcess
函数主要完成任务:
- 向
ServiceManager
添加注册了一些服务,包括AMS
自身。 - 通过
PMS 获取
"android" 系统服务的ApplicationInfo
信息,并安装到系统服务对应的LoadedApk
中。 - 构建
SystemServer
进程对应的ProcessRecord
,将SystemServer
纳入到AMS
的管理中。
Step 3 SystemServer#startOtherServices
接下来AMS启动相关的操作,在SystemServer的startOtherServices函数中
com.android.server.SystemServer
private void startOtherServices() {
...
// Step 3.1
mActivityManagerService.installSystemProviders();
...
// Step 3.2
mActivityManagerService.systemReady(new Runnable() {
...
});
}
继续跟进AMS的installSystemProviders函数
Step 3.1 AMS # installSystemProviders
com.android.server.am.ActivityManagerServer
public final void installSystemProviders() {
List<ProviderInfo> providers;
synchronized (this) {
// AMS 根据进程名取出对应的ProcessRecord
ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
// 得到该ProcessRecord对应的ProviderInfo
// Step 3.1.1
providers = generateApplicationProvidersLocked(app);
// 仅处理系统级的Provider,取出非系统
if (providers != null) {
for (int i=providers.size()-1; i>=0; i--) {
ProviderInfo pi = (ProviderInfo)providers.get(i);
if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
Slog.w(TAG, "Not installing system proc provider " + pi.name
+ ": not system .apk");
providers.remove(i);
}
}
}
}
if (providers != null) {
// 安装Provider
// Step 3.1.2
mSystemThread.installSystemProviders(providers);
}
mConstants.start(mContext.getContentResolver());
// 监控Settings数据库中的secure、System和Global表的变化
mCoreSettingsObserver = new CoreSettingsObserver(this);
// 创建监控数据库中字体大小的变化
mFontScaleSettingObserver = new FontScaleSettingObserver();
// Now that the settings provider is published we can consider sending
// in a rescue party.
RescueParty.onSettingsProviderPublished(mContext);
//mUsageStatsService.monitorPackages();
}
从上面的代码可以看出,AMS # installSystemProviders
主要是加载运行在 SystemServer
进程中的 ContentProvider
,即SettingProvider.apk
(frameworks/base/packages/SettingsProvider)
framework-res.apk 源码 SettingProvider.apkframework-res.apk 源码的位置:frameworks/base/core/res
SettingProvider.apk 源码的位置:frameworks/base/packages/SettingsProvider
上面有两个比较重要的函数:
-
generateApplicationProvidersLocked
返回一个进程对应的ProviderInfo
列表。 -
ActivityThread
可以看做进程Android运行环境,因此它的installSystemProviders
表示为对应进程安装ContentProvider
。 - 当
SettingProvider
被加载到SystemServer
进程中运行后,AMS
就注册了两个ContentObserver
监控SettingsProvider
中的字段变化
AMS 监控的字段影响范围比较广,例如字体发生变化时,很多应用的显示界面需要作出调整,这也许就是让 AMS来 负责监控这些字段的原因
接下来,我们看上面比较重要的两个函数
Step 3.1.1
com.android.server.am.ActivityServiceManager
private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
List<ProviderInfo> providers = null;
try {
// 利用 PMS 根据进程名及权限,从数据结构中得到进程对应的ProviderInfo
providers = AppGlobals.getPackageManager()
.queryContentProviders(app.processName, app.uid,
STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
| MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
.getList();
} catch (RemoteException ex) {
}
if (DEBUG_MU) Slog.v(TAG_MU,
"generateApplicationProvidersLocked, app.info.uid = " + app.uid);
int userId = app.userId;
if (providers != null) {
// 通常而言,我们逐渐向容器加入数据时,容器只有在数据超出当前存储空间时
// 才会运行内存的重新分配(一般乘2)和数据的拷贝
// 因此若待加入数据总量很大,在逐步向容器加入数据的过程,容器将会有多次重新分配和拷贝的过程
// 或许整体的开销并不是很惊人,但事先将内存一次分配到位,体现了对极致的追求
// 建议学习
int N = providers.size();
app.pubProviders.ensureCapacity(N + app.pubProviders.size());
for (int i=0; i<N; i++) {
// TODO: keep logic in sync with installEncryptionUnawareProviders
ProviderInfo cpi =
(ProviderInfo)providers.get(i);
// 判断是否为单例的
boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
cpi.name, cpi.flags);
// 针对多用户的处理
// 若一个Provider是单例的,但当前进程不属于默认用户,那么这个Provider将不被处理
// 简单来说,就是两个用户都启动一个进程时(有了两个进程)
// 定义于进程Package中单例的Provider仅运行在默认用户启动的进程中
if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
// This is a singleton provider, but a user besides the
// default user is asking to initialize a process it runs
// in... well, no, it doesn't actually run in this process,
// it runs in the process of the default user. Get rid of it.
providers.remove(i);
N--;
i--;
continue;
}
// 包名和类名组成ComponentName
ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
// 创建ContentProvider对应的ContentProviderRecord
// 加入到AMS的MProviderMap中
ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
if (cpr == null) {
cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
mProviderMap.putProviderByClass(comp, cpr);
}
// 将ContentProviderRecord保存在ProcessRecord中
app.pubProviders.put(cpi.name, cpr);
if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
// 当ContentProvider仅属于当前进程时,还需要统计该Provider的运行信息
app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
mProcessStats);
}
//通知PMS记录该Provider对应包被使用的时间
notifyPackageUse(cpi.applicationInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
}
}
return providers;
}
generateApplicationProvidersLocked
函数实现的主要功能:
- 从
PMS
中得到应用对应的ContentProvider
。 - 利用应用信息和对应的
ContentProvider
组成ContentProviderRecord
。 - 将
ContentProviderRecord
按包名保存到AMS
的mProviderMap
中。原因:AMS
需要管理。ContentProvider
,当一个进程退出时,AMS
需要将其中运行的ContentProvider
信息从系统中移除。 - 将
ContentProviderRecord
按包名保存到ProcessRecord
中。原因:最终需要落实到一个进程中。
Step 3.1.2 ActivityThread # installSystemProviders
com.android.app.ActivityThread
public final void installSystemProviders(List<ProviderInfo> providers) {
if (providers != null) {
//对于SystemServer进程而言,mInitialApplication是framework-res.apk对应的Application
installContentProviders(mInitialApplication, providers);
}
}
####### Step 3.1.2.1 ActivityThread # installContentProviders
com.android.app.ActivityThread
private void installContentProviders(
Context context, List<ProviderInfo> providers) {
final ArrayList<ContentProviderHolder> results = new ArrayList<>();
for (ProviderInfo cpi : providers) {
...
// Step 3.1.2.1.1 初始化并保存ContentProvider
ContentProviderHolder cph = installProvider(context, null, cpi,
false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
if (cph != null) {
cph.noReleaseNeeded = true;
results.add(cph);
}
}
try {
// Step 3.1.2.1.2 向AMS注册ContentProvider
ActivityManager.getService().publishContentProviders(
getApplicationThread(), results);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
installContentProviders
是安装 ContentProvider
的通用程序,主要包括两方面的工作:
- 调用
installProvider
得到ContentProviderHolder
对象,其间完成了对应ContentProvider
的初始化等工作。 - 向
AMS
发布ContentProviderHolder
。
####### Step 3.1.2.1.1 ActivityThread # installProvider
com.android.app.ActivityThread
private ContentProviderHolder installProvider(Context context,
ContentProviderHolder holder, ProviderInfo info,
boolean noisy, boolean noReleaseNeeded, boolean stable) {
ContentProvider localProvider = null;
IContentProvider provider;
if (holder == null || holder.provider == null) {
// 此时holder==null,进入这个分支
...
Context c = null;
ApplicationInfo ai = info.applicationInfo;
// 下面判断的作用是:为待安装的ContentProvider找到对应的Application
// 在 AndroidManifest中,ContentProvider是Application的子标签,因此ContentPro与Application有一种对应关系
// 本次流程中,传入的context是mInitApplication,代表的是framework-res.apk
// 而 ai 是从ProviderInfo中获取的,代表的是SettingProvider,SettingProvider.apk所对应的Application还未创建
// 所有进入最后的else判断中
if (context.getPackageName().equals(ai.packageName)) {
c = context;
} else if (mInitialApplication != null &&
mInitialApplication.getPackageName().equals(ai.packageName)) {
c = mInitialApplication;
} else {
try {
// 以下将重新创建一个Context,指向SettingProvider.apk
// ai.packageName = "com.android.provider.settings"
// createPackageContext方法中利用package对应的LoadedApk信息,创建新的ContextImpl
// 其内部通过 mMainThread.getPackageInfo 取出LoadedApk,在这个过程中,如果已经加载过就直接从存储变量中取,否则同PMS重新构建
c = context.createPackageContext(ai.packageName,
Context.CONTEXT_INCLUDE_CODE);
} catch (PackageManager.NameNotFoundException e) {
// Ignore
}
}
...
try {
// 上面必须找到ContentProvider对应的Context的原因:
// 1. ContentProvider和Application有对应关系,而Application继承Context
// 2. 只有正确的Context才能加载对应APK的Java字节码,从而通过反射创建出ContentProvider实例
// 得到对应的ClassLoader
final java.lang.ClassLoader cl = c.getClassLoader();
// 反射创建实例
localProvider = (ContentProvider)cl.
loadClass(info.name).newInstance();
// ContentProvider的mTransport对象
// 变现类型为IContentProvider,实际为ContentProviderNative,即ContentProvider的Binder通信服务端BbBinder
// Tansport 继承 ContentProviderNative
provider = localProvider.getIContentProvider();
...
// 初始化ContentProvider,内部会调用ContentProvider的onCreate函数
localProvider.attachInfo(c, info);
} catch (java.lang.Exception e) {
...
return null;
}
} else {
provider = holder.provider;
...
}
ContentProviderHolder retHolder;
synchronized (mProviderMap) {
...
// 调用ContentProviderNative的asBinder,得到服务端的Binder对象
IBinder jBinder = provider.asBinder();
if (localProvider != null) {
ComponentName cname = new ComponentName(info.packageName, info.name);
ProviderClientRecord pr = mLocalProvidersByName.get(cname);
if (pr != null) {
...
provider = pr.mProvider;
} else {
// 根据ProviderInfo创建ContenProviderHolder
holder = new ContentProviderHolder(info);
// 使持有provider
holder.provider = provider;
holder.noReleaseNeeded = true;
// 构造ProviderClientRecord,并按authority将其保存在mProviderMap中
pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
// 将 pr 按 jBinder 保存在 mLocalProviders 中
mLocalProviders.put(jBinder, pr);
// 将 pr 按 cname 保存在 mLocalProvidersByName 中
mLocalProvidersByName.put(cname, pr);
}
retHolder = pr.mHolder;
} else {
...
}
}
return retHolder;
}
installProvider
的代码较长,但实际思想很简单,就是环环相扣的三步:
- 创建出
ContentProvider
对应的ContextImpl
(代表对应的运行环境) - 利用
ContextImpl
得到对应的ClassLoader
,完成ContentProvider
的初始化和启动 - 得到与
ContentProvider
通信的BBinder
,然后按名称和BBinder
,将ContentProvider
保存到对应的存储结构中“
ActivityThread 与 ContenProvider 的关系大概如上图所示。
ContentProvider
本身只是一个容器,其内部持有的 Transport 类才是能提供跨进程调用的支持。
Transport
类继承自 ContentProviderNative
类,作为ContentProvider
的 Binder
通信服务端 BBinder
。
ContentProviderNative
中定义的 ContentProviderProxy
类将作为 Binder
通信的服务端代理,为客户端提供交互
在上面的代码中,ActivityThread
用 mLocalProviders
保存运行在本地的 ContentProvider
,使用的键值的key为 ContentProvider的Binder
通信服务端。
####### Step 3.1.2.1.1 publishContentProviders
ContentProvider
初始化完成后,我们需要向 AMS
注册它。
com.android.app.ActivityThread
private void installContentProviders(
...
ActivityManager.getService().publishContentProviders(
getApplicationThread(), results);
...
}
这段代码是注册ContentProvider的通用代码.
因此即使我们现在的流程运行在AMS中,此处仍然将通过Binder通信进行调用。
com.android.server.app.ActivityManagerService
public final void publishContentProviders(IApplicationThread caller,
List<ContentProviderHolder> providers) {
if (providers == null) {
return;
}
enforceNotIsolatedCaller("publishContentProviders");
synchronized (this) {
//找到调用者对应的ProcessRecord对象
final ProcessRecord r = getRecordForAppLocked(caller);
...
final long origId = Binder.clearCallingIdentity();
final int N = providers.size();
for (int i = 0; i < N; i++) {
// ProcessRecord的pubProviders中保存了ContentProviderRecord信息
// 这是根据PMS解析出的Package信息生成的
// 此处主要发布的ContentProvider,必须是该Packager已经声明的
ContentProviderHolder src = providers.get(i);
ContentProviderRecord dst = r.pubProviders.get(src.info.name);
...
if (dst != null) {
ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
// 按名称保存到MProviderMap
mProviderMap.putProviderByClass(comp, dst);
String names[] = dst.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
// 按 authority保存到mProviderMap
mProviderMap.putProviderByName(names[j], dst);
}
// mLaunchingProviders 保存处于启动状态的Provider
int launchingCount = mLaunchingProviders.size();
int j;
boolean wasInLaunchingProviders = false;
for (j = 0; j < launchingCount; j++) {
if (mLaunchingProviders.get(j) == dst) {
// 启动完成后,从列表中移除
mLaunchingProviders.remove(j);
wasInLaunchingProviders = true;
j--;
launchingCount--;
}
}
if (wasInLaunchingProviders) {
// 取消启动超时的消息
mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
}
synchronized (dst) {
dst.provider = src.provider;
dst.proc = r;
// 通知
dst.notifyAll();
}
// 没发布一个ContentProvider,均调整对应进程的oom_adj
updateOomAdjLocked(r, true);
// 判断,并在需要的时候更新ContentProvider相关的统计信息
maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
src.info.authority);
}
}
Binder.restoreCallingIdentity(origId);
}
}
publishContentProvider
函数结束后,一个 ContentProvider
就算正式在系统中注册了。
在 AMS
的启动过程中,此处注册的是 SettingProvider
此后,Setting数据库相关的操作均由它来管理。
注意到上面的 ContentProvider
注册到 AMS
后,进行了notifyAll
的操作。
举例来说:进程需要查询一个数据库,需要通过进程B中的某个 ContentProvider
来实施。如果 B 还未启动,那么 AMS
就需要先启动 B。在这段时间内,A需要等待B注册启动对应的 ContentProvider
。B一旦完成 ContentProvider
的注册,就需要告知A退出等待继续后续的查询工作。
Step SystemServer # systemReady
接下来,我们看看AMS启动的最后一部分:systemReady
com.android.server.SystemServer
private void startOtherServices() {
...
// Step 3.1
mActivityManagerService.installSystemProviders();
...
mPackageManagerService.systemReady();
...
// Step 3.2
mActivityManagerService.systemReady(new Runnable() {
...
});
}
在SystemServer中的startOtherServices的最后调用了AMS的systemReady函数
可以看到第一个参数为Runnable。
由于此处代码量很大,所以先分段查看 AMS
中systemReady
的处理流程,然后再查看 Runnable
中的处理流程。
Step 3.2.1 阶段一
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
traceLog.traceBegin("PhaseActivityManagerReady");
synchronized(this) {
// 第一次mSystemReady=false
if (mSystemReady) {
// If we're done calling all the receivers, run the next "boot phase" passed in
// by the SystemServer
if (goingCallback != null) {
goingCallback.run();
}
return;
}
// 这一部分主要是调用一些关键服务systemReady相关的函数
mLocalDeviceIdleController
= LocalServices.getService(DeviceIdleController.LocalService.class);
mAssistUtils = new AssistUtils(mContext);
mVrController.onSystemReady();
// Make sure we have the current profile info, since it is needed for security checks.
mUserController.onSystemReady();
mRecentTasks.onSystemReadyLocked();
mAppOpsService.systemReady();
// 系统准备完毕
mSystemReady = true;
}
try {
sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
.getSerial();
} catch (RemoteException e) {}
ArrayList<ProcessRecord> procsToKill = null;
synchronized(mPidsSelfLocked) {
for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
// mPidsSelfLocked中保存当前正在运行的所有进程的信息
ProcessRecord proc = mPidsSelfLocked.valueAt(i);
// isAllowedWhileBooting中判断FLAG_PERSISTENT标志
// 在AMS启动完成前,如果没有 FLAG_PERSISTENT 标志的进程已经启动了,将其加入到procsToKill列表中
if (!isAllowedWhileBooting(proc.info)){
if (procsToKill == null) {
procsToKill = new ArrayList<ProcessRecord>();
}
procsToKill.add(proc);
}
}
}
synchronized(this) {
if (procsToKill != null) {
for (int i=procsToKill.size()-1; i>=0; i--) {
ProcessRecord proc = procsToKill.get(i);
Slog.i(TAG, "Removing system update proc: " + proc);
// 关闭 procsToKill中的进程
removeProcessLocked(proc, true, false, "system update done");
}
}
// Now that we have cleaned up any update processes, we
// are ready to start launching real processes and know that
// we won't trample on them any more.
// 进程准备完毕
mProcessesReady = true;
}
...
// 根据数据库和资源文件,获取一些配置参数
retrieveSettings();
final int currentUserId;
synchronized (this) {
// 得到当前的用户Id
currentUserId = mUserController.getCurrentUserIdLocked();
// 读取 urigrant.xml,为其中定义的 ContentProvider 配置对指定Uri数据的访问/修改权限
// 原生的代码中,似乎没有 urigrants.xmls
// 实际使用的 grant-uri-permission 是分布式定义的
readGrantedUriPermissionsLocked();
}
if (goingCallback != null) goingCallback.run();
traceLog.traceBegin("ActivityManagerStartApps");
...
}
这部分的主要工作:
这一部分的工作主要是
- 调用一些关键服务的初始化函数
- 杀死那些没有 FLAG_PERSISTENT 却在AMS启动完成前已经存在的进程
- 获取一些配置参数。
只有Java进程才会向AMS注册,而一般的Native进程不会向AMS注册,因此这里杀死的进程时Java进程
Step 3.2.2 阶段二
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
...
// 调用参数传入的 Runnable对象,SystemServer中有具体的定义
// Step 3.2.2.1
if (goingCallback != null) goingCallback.run();
traceLog.traceBegin("ActivityManagerStartApps");
...
// 内部循环遍历所有的系统服务的onStartUser接口
mSystemServiceManager.startUser(currentUserId);
synchronized (this) {
// Only start up encryption-aware persistent apps; once user is
// unlocked we'll come back around and start unaware apps
// 启动persistent为1的Application所在的进程
// Step 3.2.2.2
startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
// Start up initial activity.
mBooting = true;
// Enable home activity for system user, so that the system can always boot. We don't
// do this when the system user is not setup since the setup wizard should be the one
// to handle home activity in this case.
// 当isSplitSystemUser返回true时,意味着system user和primary user是分离的
// 这里应该是让system user也有启动 home activity 的权限吧
if (UserManager.isSplitSystemUser() &&
Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
try {
AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
UserHandle.USER_SYSTEM);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
}
// Step 3.2.2.3 启动 Home
startHomeActivityLocked(currentUserId, "systemReady");
try {
// 发送消息,触发处理Uid错误的Application
if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
...
mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
}
} catch (RemoteException e) {
}
// 发送一些广播信息
...
// 这里暂不深入,属于Activity的启动过程,onResume
mStackSupervisor.resumeFocusedStackTopActivityLocked();
...
}
}
这部分代码的主要工作:
- 通知所有的系统服务执行onStartUser()
- 启动persistent=1的Application所在的进程
- 启动Home
- 执行Activity的onResume
Step 3.2.2.1 SystemServer.systemReady的Runnable回调函数
回调函数定义在 ServerServer#startOtherServices 中,其中会调用大量服务的 onBootPhase
函数、一些对象的systemReady
函数或 systemRunning
函数。
com.android.server.SystemServer
mActivityManagerService.systemReady(() -> {
// 遍历系统服务startBootPhase启动阶段代码
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
try {
// AMS 启动 NativeCrashListener,监听“/data/system/ndebugsocket”中的信息
// 实际上就是监听 debuggerd(调试工具) 传入的信息
mActivityManagerService.startObservingNativeCrashes();
} catch (Throwable e) {
reportWtf("observing native crashes", e);
}
// No dependency on Webview preparation in system server. But this should
// be completed before allowring 3rd party
final String WEBVIEW_PREPARATION = "WebViewFactoryPreparation";
Future<?> webviewPrep = null;
if (!mOnlyCore) {
webviewPrep = SystemServerInitThreadPool.get().submit(() -> {
Slog.i(TAG, WEBVIEW_PREPARATION);
TimingsTraceLog traceLog = new TimingsTraceLog(
SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
traceLog.traceBegin(WEBVIEW_PREPARATION);
ConcurrentUtils.waitForFutureNoInterrupt(mZygotePreload, "Zygote preload");
mZygotePreload = null;
mWebViewUpdateService.prepareWebViewInSystemServer();
traceLog.traceEnd();
}, WEBVIEW_PREPARATION);
}
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
traceBeginAndSlog("StartCarServiceHelperService");
mSystemServiceManager.startService(CarServiceHelperService.class);
traceEnd();
}
// 启动 SystemUi
try {
startSystemUi(context, windowManagerF);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
// 一系列 systemReady
try {
if (networkScoreF != null) networkScoreF.systemReady();
} catch (Throwable e) {
reportWtf("making Network Score Service ready", e);
}
...
...
// 启动Watchdog
Watchdog.getInstance().start();
// Wait for all packages to be prepared
mPackageManagerService.waitForAppDataPrepared();
// confirm webview completion before starting 3rd party
if (webviewPrep != null) {
ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION);
}
mSystemServiceManager.startBootPhase(
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
// 一系列 systemRunning
try {
if (locationF != null) locationF.systemRunning();
} catch (Throwable e) {
reportWtf("Notifying Location Service running", e);
}
...
...
}, BOOT_TIMINGS_TRACE_LOG);
Step 3.2.2.2 AMS # startPersistentApps
启动 persistent 标志的进程
com.android.server.am.ActivityManagerService
private void startPersistentApps(int matchFlags) {
...
synchronized (this) {
try {
//从PMS中得到persistent为1的ApplicationInfo
final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
.getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
for (ApplicationInfo app : apps) {
//由于framework-res.apk已经由系统启动,所以此处不再启动它
if (!"android".equals(app.packageName)) {
// addAppLocked中将启动application所在进程
addAppLocked(app, false, null /* ABI override */);
}
}
} catch (RemoteException ex) {
}
}
}
跟进一下 addAppLocked 函数
com.android.server.am.ActivityManagerService
final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
String abiOverride) {
//以下是取出或构造出ApplicationInfo对应的ProcessRecord
ProcessRecord app;
if (!isolated) {
app = getProcessRecordLocked(info.processName, info.uid, true);
} else {
app = null;
}
if (app == null) {
app = newProcessRecordLocked(info, null, isolated, 0);
updateLruProcessLocked(app, false, null);
updateOomAdjLocked();
}
...
// This package really, really can not be stopped.
try {
//通过PKMS将package对应数据结构的StoppedState置为fasle
AppGlobals.getPackageManager().setPackageStoppedState(
info.packageName, false, UserHandle.getUserId(app.uid));
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
}
if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
app.persistent = true;
app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
}
if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
mPersistentStartingProcesses.add(app);
//启动应用所在进程,将发送消息给zygote,后者fork出进程
startProcessLocked(app, "added application", app.processName, abiOverride,
null /* entryPoint */, null /* entryPointArgs */);
}
return app;
}
这里最终通过 startProcessLocked
函数,启动实际的应用进程。
Zygote
进程中的 server socket
将接受消息,然后为应用fork出进程
Step 3.2.2.3 AMS # startHomeActivityLocked
启动Home Activity
com.android.server.am.ActivityManagerService
boolean startHomeActivityLocked(int userId, String reason) {
...
Intent intent = getHomeIntent();
//根据intent中携带的ComponentName,利用PMS得到ActivityInfo
ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
//此时home对应进程应该还没启动,app为null
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
if (app == null || app.instrumentationClass == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
//启动home
mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
}
} else {
...
}
return true;
}
这里暂时不深究Home Activity启动的具体过程。当启动成功后,会调用Activity#handleResumeActivity方法,最终调用到 ActivityStackSupervisor#activityIdleInternalLocked。
com.android.server.am.ActivityStackSupervisor
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
Configuration config) {
...
if (isFocusedStack(r.task.stack) || fromTimeout) {
booting = checkFinishBootingLocked();
}
...
}
跟进一下 checkFinishBootingLocked
函数
com.android.server.am.ActivityStackSupervisor
private boolean checkFinishBootingLocked() {
//mService为AMS,mBooting变量在AMS回调SystemServer中定义的Runnable时,置为了true
final boolean booting = mService.mBooting;
boolean enableScreen = false;
mService.mBooting = false;
if (!mService.mBooted) {
mService.mBooted = true;
enableScreen = true;
}
if (booting || enableScreen) {、
//调用AMS的接口,发送消息
mService.postFinishBooting(booting, enableScreen);
}
return booting;
}
最终,AMS
的 finishBooting
函数将被调用:
com.android.server.am.ActivityManagerService
final void finishBooting() {
...
//以下是注册广播接收器,用于处理需要重启的package
IntentFilter pkgFilter = new IntentFilter();
pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
pkgFilter.addDataScheme("package");
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
if (pkgs != null) {
for (String pkg : pkgs) {
synchronized (ActivityManagerService.this) {
if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
0, "query restart")) {
setResultCode(Activity.RESULT_OK);
return;
}
}
}
}
}
}, pkgFilter);
...
// Let system services know.
mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
//以下是启动那些等待启动的进程
synchronized (this) {
// Ensure that any processes we had put on hold are now started
// up.
final int NP = mProcessesOnHold.size();
if (NP > 0) {
ArrayList<ProcessRecord> procs =
new ArrayList<ProcessRecord>(mProcessesOnHold);
for (int ip=0; ip<NP; ip++) {
...
startProcessLocked(procs.get(ip), "on-hold", null);
}
}
}
}
...
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
// Start looking for apps that are abusing wake locks.
//每5min检查一次系统各应用进程使用电量的情况,如果某个进程使用WakeLock的时间过长
//AMS将关闭该进程
Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
// Tell anyone interested that we are done booting!
SystemProperties.set("sys.boot_completed", "1");
...
//此处从代码来看发送的是ACTION_LOCKED_BOOT_COMPLETED广播
//在进行unlock相关的工作后,mUserController将调用finishUserUnlocking,发送SYSTEM_USER_UNLOCK_MSG消息给AMS
//AMS收到消息后,调用mUserController的finishUserUnlocked函数,经过相应的处理后,
//在mUserController的finishUserUnlockedCompleted中,最终将会发送ACTION_BOOT_COMPLETED广播
mUserController.sendBootCompletedLocked(...);
...
}
}
最终AMS启动 HomeActivity 结束,并发送 ACTION_BOOT_COMPLETED 广播时,AMS的启动过程告一段落。
总结
对于整个AMS
启动过程来说,本文涉及的内容只是其中极小一部分。
整个过程,可以将AMS的启动过程分为四步
-
创建出 SystemServer 进程的 Android 运行环境
这个流程,创建SystemServer进程对应的ActivityThread和ContextImpl,构成Android运行环境
AMS后续工作依赖SystemServer在此创建出的运行环境 -
完成AMS的初始化和启动
这个流程,调用了AMS的构造函数和start函数,完成AMS一些初始化工作 -
将SystemServer进程纳入到AMS的管理体系
这个流程,AMS加载了SystemServer中framework-res.apk的信息,并启动和注册了SettingsProvider.apk。涉及了ContentProvider的安装。 -
AMS启动完毕后才能进行的工作
这个流程,AMS调用 systemReady函数,通知系统的其他服务和进程,可以进行对应的工作。
并且,Home Activity被启动了,当Home Activity被加载完成后,最终会触发ACTION_BOOT_COMPLETED广播。
- 创建
system
进程的运行环境,一个ActivityThread
主线程,一个和系统进程相关的Context
对象 - 调用
AMS
的构造方法,对必要的内容进行初始化 - 将 AMS 注册到
ServiceManager
中,同时对system
进程创建一个ProcessRecord
对象,并设置Context
的application
为framework-res
的application
对象。由于AMS
是Android
世界的进程管理和调度中心,尽管system
贵为系统进程,也要将其并入AMS
的管理范围 - 为
system
进程加载SettingProvider
- 调用
systemReady
方法做系统启动完毕前的最后一些扫尾工作。最HomeActivity
将呈现在用户面前
网友评论