AMS系列①—AMS的启动
AMS作为Android FrameWork中最核心的一个部分,是应用层开发者进阶的里程碑,本文是AMS专栏的第一篇文章,介绍AMS的启动相关:
在学习AMS之前,需要掌握一些基础知识:
在学习完上面的内容后,我们可以知道AMS的启动是由SystemServer进程发起的:
AMS的入口方法SystemServer的main()做了两件事:
- 调用
CreateSystemContext()
创建SystemContext - 开启三类服务:引导服务,核心服务,其他服务
1. SystemServer.createSystemContext():
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
}
ActivityThread.systemMain():
public static ActivityThread systemMain() {
ActivityThread thread = new ActivityThread();
thread.attach(true, 0);
return thread;
}
在SystemMain中,首先创建了一个SystemServer进程的ActivityThread,没错,这就是用户进程的入口main的那个ActivityThread,所以从某种意义上讲,我们也可以将SystemServer进程看成一个App;
调用了ActivityThread的attach(),注意,这里传入的是true
,而我们正常的App传入的是false,这个字段表示是否是系统进程(SystemServer进程):
ActivityThread.attach():
private void attach(boolean system, long startSeq) {
...
if (!system) { // 如果是正常App进程,传入false
...
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
}
...
} else { // 如果是SystemServer进程,传入true
...
try {
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
}
}
}
如果是正常的APP,那么进入if逻辑,调用AMS的代理发起一次Binder消息,实际调用AMS的attachApplication();
在本次情况中是由SystemServer进程发起的,进入else逻辑:
- 调用ContextImpl.createAppContext()创建App Context
- 注意上一个方法,传入了一个
getSystemContext().mPackageInfo
参数 - 调用makeApplication创建Application
我们先来看传入的参数:
ActivityThread.getSystemContext()
public ContextImpl getSystemContext() {
synchronized (this) {
mSystemContext = ContextImpl.createSystemContext(this);
}
getSystemContext()调用了ContextImpl的createSystemContext():
ContextImpl.createSystemContext():
static ContextImpl createSystemContext(ActivityThread mainThread) {
LoadedApk packageInfo = new LoadedApk(mainThread);
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
null);
context.setResources(packageInfo.getResources());
return context;
}
ContextImpl有一系列的创建Context的static 方法:
在这里创建了SystemContext,Context的具体作用就是用来获取资源,比如你的Activity需要使用apk里面的资源,而系统SystemServer也需要使用系统预设的资源文件,所以在这里也创建了一个Context对象;
那么Context是如何获取资源的呢?答案是LoadedApk
这个类,LoadedApk是apk文件在内存中的存在形式
所以一般ApplicationContext或者ActivityContext都会持有它对应的apk文件的内存形式LoadedApk对象;那么我们的SystemServer是跟哪个APK绑定呢???看下面这张图就明白了:
虽然它是一个LoadedAPK对象,但是并没有对应apk文件,它存在的意义就是为SystemContext服务,为它提供获取系统资源的能力;注意倒数第二第三行,SystemClassLoader,SystemResource,如果是通过其他构造方法创建的LoadedApk,就不会有这个值,他们是通过对应apk文件解析出来的数据;
至此,我们的SystemContext创建完毕,回到ActivityThread.attach():这一步,参数看好了,参数就是SystemContext的LoadedApk,就是那个没有apk的LoadedAPK;
ContextImpl.CreateAppContext:
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;
}
在这里因为传入的LoadedAPK是被阉割的LoadedAPK对象,所以这个ApplicationContext,本质上和SystemContext一样,他们的resource都是System Resource;
context.mPackageInfo.makeApplication(true, null):
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
...
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
}
...
return app;
}
mInstrumentation.newApplication()
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = getFactory(context.getPackageName())
.instantiateApplication(cl, className);
app.attach(context);
return app;
}
makeApplication的逻辑就是创建Application对象,然后调用Application的attach方法:
/* package */ final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
保存Application Context 和 LoadedApk到Application
至此SystemServer创建System Context的操作分析完毕,下面分析SystemServer的run()中开启三类服务中关于AMS的逻辑
SystemServer.startBootstrapServices():
private void startBootstrapServices() {
...
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setInstaller(installer);
mActivityManagerService.initPowerManagement();
mActivityManagerService.setSystemProcess();
}
在启动引导服务startBootstrapServices
这个方法中,涉及AMS的逻辑主要做了四件事:
- 创建AMS实例
- 设置installer,App安装器
- 初始化PMS
- 调用setSystemProcess()
1. startService(ActivityManagerService.Lifecycle.class).getService();
startService()传入了一个AMS的内部类Lifecycle的Class对象,会创建一个Lifecycle的实例,接着这个Lifecycle会调用自己的getService方法获取AMS实例:
public Lifecycle(Context context) {
super(context);
mService = new ActivityManagerService(context);
}
public ActivityManagerService getService() {
return mService;
}
下面看一下AMS的构造方法,AMS的构造方法中,做了很多事情:
public ActivityManagerService(Context systemContext) {
...
// 前台服务线程
mHandlerThread = new ServiceThread(TAG,
THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
// 后台服务线程
sKillThread = new ServiceThread(TAG + ":kill",
THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
// CPU线程
mProcessCpuThread = new Thread("CpuTracker") ;
// AMS家族:
mConstants = new ActivityManagerConstants(this, mHandler);
mServices = new ActiveServices(this);
mStackSupervisor = createStackSupervisor();
mActivityStartController = new ActivityStartController(this);
// 开启 watch dog
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
// 创建 AppOpsService , Android原生应用程序权限管理相关
mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
//创建进程状态服务,监听进程转发服务
mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
//创建电量状态服务
mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
}
在AMS的构造方法中,大概做了以下几件事:
- 创建各个工作线程,前台服务线程,后台服务线程,CPU线程
- 实例化AMS家族成员,ActivityManagerConstants,ActiveServices,StackSupervisor,ActivityStartController,这些在后续会详细介绍;
- 开启各种服务,watch dog,Appops,ProcessStatsService,BatteryStatsService
- 软件看门狗来监控SystemServer中的线程。一旦发现问题,WatchDog会杀死SystemServer进程。SystemServer的父进程Zygote接收到SystemServer的死亡信号后,会杀死自己。Zygote进程死亡的信号传递到Init进程后,Init进程会杀死Zygote进程所有的子进程并重启Zygote。这样整个手机相当于重启一遍。通常SystemServer出现问题和kernel并没有关系,所以这种“软重启”大部分时候都能够解决问题。而且这种“软重启”的速度更快,对用户的影响也更小。
至此,第一步AMS的实例化分析完毕,步骤2 和 步骤3 是设置APk安装器和初始化PMS,不做过多介绍,下面详细看下步骤4setSystemProcess()
4 mActivityManagerService.setSystemProcess();
public void setSystemProcess() {
try {
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);
ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_HIGH);
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(this),
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
}
ServiceManager.addService("permission", new PermissionController(this));
ServiceManager.addService("processinfo", new ProcessInfoService(this));
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
synchronized (this) {
ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
}
}
// Start watching app ops after we and the package manager are up and running.
mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null);
}
在AMS的setSystemProcess()中主要做了四件事:
- 添加各种服务到ServiceManager中:this(自己AMS服务),内存,图像,权限,cpu,进程,相关服务
- installSystemApplicationInfo
- 创建ProcessRecord对象
- 调用AppOps服务的startWatch方法开启对应用程序包给定权限的监听;
步骤2:installSystemApplicationInfo():
public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
synchronized (this) {
getSystemContext().installSystemApplicationInfo(info, classLoader);
getSystemUiContext().installSystemApplicationInfo(info, classLoader);
// give ourselves a default profiler
mProfiler = new Profiler();
}
}
步骤2做了两件事:
- 将ApplicationInfo对象设置给SystemContext
- 创建Profiler对象,用于性能统计
至此SystemService开启引导服务中AMS相关的逻辑分析完毕;
SystemServer.startOtherServices():
mActivityManagerService.systemReady(() -> {
mSystemServiceManager.startBootPhase(
try {
mActivityManagerService.startObservingNativeCrashes();
}
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
mVrController.onSystemReady();
mUserController.onSystemReady();
mRecentTasks.onSystemReadyLocked();
mAppOpsService.systemReady();
mSystemReady = true;
startHomeActivityLocked(currentUserId, "systemReady");
}
在startOtherServices()中,AMS的主要逻辑就是调用了SystemReady()开启一个Activity,开启Activity的内容后期再讲,会设计AMS的大家族;