ZygoteInit.main()方法是Android中Java世界的入口,我们跟随这个方法来看看SystemServer的启动流程。
源码文件位置
- frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
- frameworks\base\core\java\com\android\internal\os\Zygote.java
- frameworks\base\core\java\com\android\internal\os\ZygoteServer.java
- frameworks\base\core\java\com\android\internal\os\RuntimeInit.java
ZygoteInit.main()
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
// Mark zygote start. This ensures that thread creation will throw
// an error.
ZygoteHooks.startZygoteNoThreadCreation();
final Runnable caller;
try {
...
//SystemServer是否开启的标记
boolean startSystemServer = false;
//服务端Socket的名称
String socketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
//根据JNI层传递过来的消息,来判断是否启动SystemServer
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
if (abiList == null) {
throw new RuntimeException("No ABI list supplied.");
}
/**
* 1. 注册Zygote用的socket,名称为上面的socketName
*/
zygoteServer.registerServerSocketFromEnv(socketName);
// In some configurations, we avoid preloading resources and classes eagerly.
// In such cases, we will preload things prior to our first fork.
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
/**
* 2. 预加载类和资源
*/
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
}
// Do an initial gc to clean up after startup
bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
gcAndFinalize(); //强制执行垃圾回收
bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
...
/**
* 3. 启动SystemServer进程
*/
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
Log.i(TAG, "Accepting command socket connections");
/**
* 4. 处理客户端连接和客户端请求。其中客户在zygote中用ZygoteConnection对象来表示
* 客户端的请求由ZygoteConnection的processOneCommand方法处理
* (等待AMS请求)
*/
// The select loop returns early in the child process after a fork and
// loops forever in the zygote.
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
zygoteServer.closeServerSocket(); //清理或关闭对应的Socket
}
// We're in the child process and have exited the select loop. Proceed to execute the
// command.
if (caller != null) {
caller.run();
}
}
接下来详细分析ZygoteInit.main()方法中的5大工作
- 建立IPC通信服务端——registerServerSocketFromEnv
Zygote及系统中其它程序的通信没有使用Binder,而是采用了基于AF_UNIX类型的Socket。registerServerSocketFromEnv()方法的使用就是建立这个Socket。
void registerServerSocketFromEnv(String socketName) {
if (mServerSocket == null) {
int fileDesc;
/**
* 1. 拿到Socket的名称
*/
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
/**
* 2. 得到Socket环境变量的值
*/
String env = System.getenv(fullSocketName);
/**
* 3. 将Socket环境变量的值转换为文件描述符的参数
*/
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(fullSocketName + " unset or invalid", ex);
}
try {
/**
* 4. 创建文件描述符
*/
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
/**
* 5. 创建服务端Socket,这个Socket将监听并接收客户端
*/
mServerSocket = new LocalServerSocket(fd);
mCloseSocketFd = true;
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
- 预加载类和资源——preload()
在preload()方法中调用了preloadClasses()和preloadResources()方法,preloadClasses()方法加载类,preloadResources()方法加载framework-res.apk中的资源。在这里我们只看看preloadClasses()。
private static void preloadClasses() {
final VMRuntime runtime = VMRuntime.getRuntime();
//预加载类的信息存储在PRELOADED_CLASSES变量中,它的值为"preload-classes"
InputStream is;
try {
is = new FileInputStream(PRELOADED_CLASSES);
} catch (FileNotFoundException e) {
Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
return;
}
...
try {
BufferedReader br = new BufferedReader(new InputStreamReader(is), 256);
//读取文件的每一行,忽略#开头的注释行和空白行
int count = 0;
String line;
while ((line = br.readLine()) != null) {
// Skip comments and blank lines.
line = line.trim();
if (line.startsWith("#") || line.equals("")) {
continue;
}
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);
try {
if (false) {
Log.v(TAG, "Preloading " + line + "...");
}
// Load and explicitly initialize the given class. Use
// Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
// (to derive the caller's class-loader). Use true to force initialization, and
// null for the boot classpath class-loader (could as well cache the
// class-loader of this class in a variable).
//通过反射来加载类,line中存储的是预加载的类名
Class.forName(line, true, null);
count++;
} catch (ClassNotFoundException e) {
Log.w(TAG, "Class not found for preloading: " + line);
} catch (UnsatisfiedLinkError e) {
Log.w(TAG, "Problem preloading " + line + ": " + e);
} catch (Throwable t) { ... }
}
} catch (IOException e) {
Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
} finally { ... }
}
preloadClasses()方法看起来并没有很复杂,但是它要预先加载的类有多少呢?在frameworks下搜索"preloaded-classes"的文件,会发现这是一个文本文件,它里面有6558行,因此preloadClasses()方法执行的时间比较长,这也是Android系统启动慢的原因之一。说明:preloaded-class文件由frameworks/base/tools/preload工具生成,他需要判断每个类加载的时间是否大于1250微秒,超过这个时间的类就会被写到preloaded-classes文件中,最后由Zygote预加载。在UI编程中常使用的com.android.R.XXX资源是系统默认的资源,它们就是由zygote加载的。
- 启动system_server
forkSystemServer()方法会创建Java世界中系统Service所驻留的进程system_server,该进程是frameworks的核心,如果它死了,就会导致Zygote自杀。
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_IPC_LOCK,
OsConstants.CAP_KILL,
OsConstants.CAP_NET_ADMIN,
OsConstants.CAP_NET_BIND_SERVICE,
OsConstants.CAP_NET_BROADCAST,
OsConstants.CAP_NET_RAW,
OsConstants.CAP_SYS_MODULE,
OsConstants.CAP_SYS_NICE,
OsConstants.CAP_SYS_PTRACE,
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG,
OsConstants.CAP_WAKE_ALARM,
OsConstants.CAP_BLOCK_SUSPEND
);
/* Containers run without some capabilities, so drop any caps that are not available. */
StructCapUserHeader header = new StructCapUserHeader(
OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
StructCapUserData[] data;
try {
data = Os.capget(header);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to capget()", ex);
}
capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
/* Hardcoded command line to start the system server */
//启动system_server的参数
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--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",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
//把上面字符串数组参数转换成Arguments对象
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
if (profileSystemServer) {
parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}
/* Request to fork the system server process */
//请求fork一个system_server进程
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
//如果pid为零,则表示处于子进程中,也就是system_server进程中
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
//system_server进程的工作
return handleSystemServerProcess(parsedArgs);
}
return null;
}
- handleSystemServerProcess()
在handleSystemServerProcess()方法中创建了PathClassLoader,相当于可以动态加载JAR/ZIP/APK,最后调用ZygoteInit.zygoteInit()方法。
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
...
if (parsedArgs.invokeWith != null) {
String[] args = parsedArgs.remainingArgs;
// If we have a non-null system server class path, we'll have to duplicate the
// existing arguments and append the classpath to it. ART will handle the classpath
// correctly when we exec a new process.
if (systemServerClasspath != null) {
String[] amendedArgs = new String[args.length + 2];
amendedArgs[0] = "-cp";
amendedArgs[1] = systemServerClasspath;
System.arraycopy(args, 0, amendedArgs, 2, args.length);
args = amendedArgs;
}
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
//创建了PathClassLoader,相当于可以动态加载JAR/ZIP/APK
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
/* should never reach here */
}
- 接下来看看zygoteInit()方法
在zygoteInit()方法中调用Native()方法启动Binder线程池,使得SystemServer能够与其它进程进行通信。然后调用了applicationInit()传入类名等参数给findStaticMain()方法。
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
//Native方法,启动Binder线程池,使得SystemServer能够与其它进程进行通信
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
- findStaticMain()方法
在findStaticMain()方法中通过反射获得SystemServer的main()方法和参数,并返回一个MethodAndArgsCaller对象。
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
//通过反射得到SystemServer类
//className是通过AMS等其它地方传递过来得,并不是唯一
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
/*
* This throw gets caught in ZygoteInit.main(), which responds
* by invoking the exception's run() method. This arrangement
* clears up all the stack frames that were required in setting
* up the process.
*/
//将SystemServer的main()方法和参数传入MethodAndArgsCaller
//然后在ZygoteInit.main()中调用其run()方法。
return new MethodAndArgsCaller(m, argv);
}
- MethodAndArgsCaller.run()
在MethodAndArgsCaller.run()方法调用调用了mMethod.invoke()方法来启动SystemServer的main()方法,至此,SystemServer的启动流程就结束了。
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}