系列文章索引
Android系统启动流程
前言
Android源码启动篇终于到了最后一个重要的内容–SystemServer(系统服务),接下来我们就来看看SystemServer为什么这么重要吧
SystemServer是Android基本服务的提供者,是Android系统运行的最基本需求,所有service运行在一个叫system_server
的进程中,system_server
进程是Android中Java虚拟机中的第一个进程,可以说,整个Android
系统的业务都是围绕system_server
而展开的
SystemServer是由Zygotefork
出来的第一个进程,我们在上篇文章中也提到了,这里我们再来回顾下,在ZygoteInit类的main函数中,通过调用forkSystemServer(),内部采用硬编码的方式创建相关参数,启动SystemServer,由此正式进入SystemServer的相关业务逻辑中
ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
...
/* Hardcoded command line to start the system server */
// "通过硬编码的方式提供相关的参数"
String args[] = {
"--setuid=1000", //用户id
"--setgid=1000",//用户组id
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
+ "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities, //进程权能
"--nice-name=system_server", //进程niceName
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer", //需要启动的类
};
ZygoteArguments parsedArgs = null;
int pid; //processId,进程id
try {
parsedArgs = new ZygoteArguments(args); //"创建ZygoteArguments对象,把args解析为需要的参数"
Zygote.applyDebuggerSystemProperty(parsedArgs);
Zygote.applyInvokeWithSystemProperty(parsedArgs);
boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
if (profileSystemServer) {
parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}
/* Request to fork the system server process */
pid = Zygote.forkSystemServer( // "fork创建SystemServer"
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
...
}
我们先来看一下整体的梳理
从上面这张流程图可以看到,SystemServer的主要流程其实还是比较简单的:
设置相关系统属性,并做一些准备工作
对Vm进行相关设置
创建主线程Looper
创建SystemServiceManager
创建ActivityThread及系统上下文Context
开启各种服务
//使用ServiceManger开启服务,并对这些服务进行管理
startBootstrapServices(); //引导服务
startCoreServices();//核心服务
startOtherServices(); //其他服务
进入Looper.loop的无限循环中
我们来看看SystemServer具体开启了哪些服务
可以看到这里面开启了很多的服务,所以,分成了三个函数类分类进程开启,
这些服务,是通过调用SystemServiceManger.startServeice()
,获取到参数传递的Class对象,使用反射的方式,获取到该类的构造器,创建该类的实例对象,并把该service
对象添加到一个ArrayList
列表中进行维护,最终调用service.onstart()
,完成服务的开启任务
这里还要说一下,所有的服务,都是SystemService
的子类对象,SystemService
是一个抽象类,内部的onstart()是一个抽象方法,最终真正执行的逻辑是其子类对象自己去定义的
那么我们这里就可以先思考下,如果我们想添加一个自定义的系统服务,应该如何去做?这里先不做深究
"ssm"中根据Class对象反射创建指定的Service对象
public T startService(Class serviceClass) {
try {
final String name = serviceClass.getName();
Slog.i(TAG, "Starting " + name);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);
// Create the service.
if (!SystemService.class.isAssignableFrom(serviceClass)) {
throw new RuntimeException("Failed to create " + name
+ ": service must extend " + SystemService.class.getName());
}
final T service;
try {
Constructor 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);
}
startService(service);
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
添加到mServices的列表中进行维护,并维护这些服务的生命中周期事件,执行该服务的onStart()
函数
// Services that should receive lifecycle events.
private final ArrayList mServices = new ArrayList();
public void startService(@NonNull final SystemService service) {
// Register it.
mServices.add(service);
// Start it.
long time = SystemClock.elapsedRealtime();
try {
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ ": onStart threw an exception", ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}
ActivityManagerService
是在startBootstrapServices
函数中开启的服务,我们来具体看下,它是如何被创建和启动的
这里主要涉及到了三个类,ActivityTaskManagerService
,ActivityManagerService
,SystemServiceManager
private void startBootstrapServices() {
...
//此处是通过"ssm"反射创建"atm"的静态内部类对象,并通过"Lifecycle"提供的"getService()"获取到"atm"实例对象
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
//调用"ams"的静态内部类的静态方法"startService"函数,把"ssm"和"atm"传递过去
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm);//内部还是使用"ssm"来创建的"ams"
...
}
具体如何启动的上面的代码注释已经解释的很清楚了,其中ATM和AMS中有着相似的设计,都是通过静态内部类Lifecycle来创建和获取本类对象,即当前系统服务的,关于AMS和Lifecycle我们后面有机会再做深究
WMS
是通过调用startOtherServices
在其他服务中开启的, 可以看出来这里的开启方式跟AMS
不太一样了,这里并不是使用SSM的StartService()
函数来开启的,而是先通过WMS的静态工厂函数main()
先创建出WMS对象,再通过ServiceManager
的addService()
函数,通过Binder机制进行进程间通信,把WMS注册到系统的服务表中
创建WMS
对象并添加到ServiceManger
中
private void startOtherServices() {
// WMS needs sensor service ready
ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
mSensorServiceStart = null;
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
}
通过addServcie
添加到ServiceManager
中
public static void addService(String name, IBinder service, boolean allowIsolated,
int dumpPriority) {
try {
getIServiceManager().addService(name, service, allowIsolated, dumpPriority);//获取到ServiceManger对象并把`WMS`添加进去
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
通过上面的源码分析,我们得知,有两种开启服务的方式,下面我们就来具体分析下
SSM这个类,目的是对系统服务「com.android.server.SystemService」的生命周期事件(创建,开启和其他事件)进行管理
SystemService
生命周期既然是对其生命周期进行管理,那先来看看系统服务都有哪些生命周期的方法
跟Activty的生命周期一样,SystemService的生命周期方法也是onxxx()
的函数命名的
SystemServiceManager
管理SystemService
的生命周期AMS的系统服务是通过SystemServiceManager
的startService()
函数,创建并开启指定className的系统服务,我们来看下具体的代码
/**
* 通过Classname创建(或者说开启)一个系统服务
* Starts a service by class name.
*
* @return The service instance.
*/
@SuppressWarnings("unchecked")
public SystemService startService(String className) {
//反射创建系统服务
final Class serviceClass;
try {
serviceClass = (Class)Class.forName(className);
} catch (ClassNotFoundException ex) {
Slog.i(TAG, "Starting " + className);
throw new RuntimeException("Failed to create service " + className
+ ": service class not found, usually indicates that the caller should "
+ "have called PackageManager.hasSystemFeature() to check whether the "
+ "feature is available on this device before trying to start the "
+ "services that implement it", ex);
}
return startService(serviceClass); //启动创建好的系统服务
}
启动服务,调用系统服务的onStart()
生命周期方法
public void startService(@NonNull final SystemService service) {
// Register it.
mServices.add(service);
// Start it.
long time = SystemClock.elapsedRealtime();
try {
service.onStart(); //调用已创建好的系统服务的onStart方法,完成初始化工作
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ ": onStart threw an exception", ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}
其他的生命周期方法调用也是在SystemServiceManager
中进行调用的,这里不再具体分析
ServiceManger中主要的函数有
添加系统服务
获取系统服务
从service manager中检索指定name的系统服务是否存在
返回正在运行的所有服务
通过这些函数可以看到,ServiceManger是对所有的系统服务进行管理,而SystemServiceManager
是对单个系统服务的创建和生命周期进行管理
我们其实还可以进一步来思考下,为什么AMS
通过SystemServiceManager
来添加,而WMS
是通过ServiceManger
来添加呢?这里先卖个关子,大家可以在评论中提出自己的看法
启动篇的源码分析断断续续做了一个多月的时间,写到这里我们就把Android源码启动篇完全分析完了,可以先告一段落了,接下来,会对AMS,WMS,以及Binder相关内容进行详尽的源码分析。由于水平有限,写的不对的还请各位多多指教
原创不易,坚持更难
如果你想继续看到我接下来的分享,请通过点赞的方式告诉我,你的鼓励是我继续创作的最大动力!