一、概述
Android 操作系统是基于Linux内核的,内核启动后,首先会加启动用户空间的第一个进程,也就是init进程,最后会调用/system/core/init/init.cpp的main()函数,它是init的入口函数。
int main(int argc, char** argv) {
if (is_first_stage) {
...
//创建文件并挂载
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
mkdir("/dev/pts", 0755);
mkdir("/dev/socket", 0755);
mount("devpts", "/dev/pts", "devpts", 0, NULL);
#define MAKE_STR(x) __STRING(x)
mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
// Don't expose the raw commandline to unprivileged processes.
chmod("/proc/cmdline", 0440);
gid_t groups[] = { AID_READPROC };
setgroups(arraysize(groups), groups);
mount("sysfs", "/sys", "sysfs", 0, NULL);
mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
...
}
...
//初始属性相关资源
property_init();
...
//启动属性服务
start_property_service();
...
//解析init.rc配置文件
LoadBootScripts(am, sm);
...
return 0;
}
总结init进程的主要工作:
- 创建和挂载启动所需要的文件和目录。
- 初始化和启动属性服务。
- 通过解析init.rc 和 其他对应rc文件,启动相应的系统级进程,其中就包括Zygote进程。
import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /init.usb.configfs.rc
import /init.${ro.zygote}.rc
...
再来看看zygote.rc配置文件(以init.zygote32.rc为例)
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
这段配置文件要求init进程创建一个名为zygote的进程,该进程要执行的程序是/system/bin/app_process,并且未zygote进程创建一个socket资源(用于进程间通信,ActivityManagerService就是通过socket请求zygote进程 fork一个应用程序进程)。 后面的“--zygote”是传给app_process的参数,表示启动的是zygote进程,会执行app_main.cpp里面的main()函数。
二、Zygote启动流程
上面已经讲述Zygote进程是如何启动的了;Zygote进程是如何从Native世界到Java世界的?
2.1 Zygote的Native世界
从上面分析我们知道Zygote启动会调用app_main.cpp里面的main()函数;
int main(int argc, char* const argv[]){
...
//解析启动Zygote进程传递的参数
// Parse runtime arguments. Stop at first unrecognized option.
bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName;
String8 className;
++i; // Skip unused "parent dir" argument.
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
} else {
--i;
break;
}
}
...
//通过runtime启动zygote
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
}
...
}
真正由Native世界到java世界是通过AndroidRuntime的start函数;
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){
...
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
//开启虚拟机
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
/*
* Register android functions.
*/
//注册系统JNI函数
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
...
//找到ZygoteInit的main函数,通过JNI调用,Zygote进入java框架层
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
2.2 Zygote Java世界 ZygoteInit.java
public static void main(String argv[]) {
//1、创建ZygoteServer
ZygoteServer zygoteServer = new ZygoteServer();
.......
try {
.......
boolean startSystemServer = false;
String socketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
// 2、解析app_main.cpp传来的参数
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.");
}
//3、创建一个Server端的Socket
zygoteServer.registerServerSocket(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());
//4、加载进程的资源和类
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
}
........
if (startSystemServer) {
//5、开启SystemServer进程,这是Zygote进程的第一次分裂
startSystemServer(abiList, socketName, zygoteServer);
}
Log.i(TAG, "Accepting command socket connections");
//6、启动一个死循环监听来自Client端的消息
zygoteServer.runSelectLoop(abiList);
//7、关闭SystemServer的Socket
zygoteServer.closeServerSocket();
} catch (Zygote.MethodAndArgsCaller caller) {
// 8、运行MethodAndArgsCaller的run方法
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}
}
ZygoteInit的main方法大概就做了上面六件事情:
- 创建ZygoteServer。
- 解析app_main.cpp传来的参数。
- 创建一个Server端的Socket,作用是当Zygote进程将SystemServer进程启动后,就会在这个Socket上来等待ActivityManagerService请求,创建我们自己App应用程序进程。
- 预加载类和资源,包括颜色啊,R文件,drawable、类等。
- 启动SystemServer进程,这是上层Framework的运行载体,ActivityManagerService就是运行在这个进程里面的。
- 开启一个循环,等待着接收ActivityManagerService的请求创建新的应用程序进程。
三、SystemServer
SystemServer进程主要用于创建系统服务,我们熟悉的AMS、WMS、PMS都是由它来创建的。
在前面讲过,Zygote进程启动了SystemServer进程,启动部分代码码:
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
...
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
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 */
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 */
//判断是否是SystemServer进程
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
//关闭Zygote的Socket
zygoteServer.closeServerSocket();
//启动SystemServer进程
return handleSystemServerProcess(parsedArgs);
}
return null;
}
fork()函数:在Linux系统内,创建子进程的方法是使用系统调用fork()函数,fork()函数调用一次会得到两个返回值: 函数返回值:
- 0 表示子进程
- 大于0 父进程,返回值为创建出的子进程的PID
- -1 出错 fork函数用于从一个已经存在的进程创建一个新进程,新的进程称为“子进程”,相应的创建子进程的进程为“父进程”。使用fork函数得到的子进程是父进程的复制品,子进程完全复制了父进程的资源,包括进程上下文、代码区、堆栈区、内存信息等等。 由于SystemServer进程是Zygote进程fork出来的,当返回值 pid为0 的时候就代表创建的是SystemServer进程,SystemServer也会有一个zygoteServer所开启的Socket实例副本,在这里并不需要这个Socket,所以关闭。
接下来看下handleSystemServerProces()方法。
/**
* Finish remaining work for the newly forked system server process.
*/
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
...
ClassLoader cl = null;
if (systemServerClasspath != null) {
//在这里创建了PathClassLoader
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
//zygoteInit方法
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
...
}
接下里看看zygoteInit方法。
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
...
//启动了Binder线程池
ZygoteInit.nativeZygoteInit();
//进入SystemServer的main方法
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
nativeZygoteInit是Native层的代码,用来启动Binder线程池,这样SystemServer进程就可以使用Binder与其他进程进行通信了。
applicationInit方法,用于启动SystemServer。
protected static void applicationInit(int targetSdkVersion,String[] argv,ClassLoader classLoader){
...
invokeStaticMain(args.startClass,args.startArgs,classLoader);
}
...
private static void invokeStaticMain(String className,String[] argv,ClassLoader classLoader){
Class<?> cl;
...
//className是com.android.server.SystemServer
cl=Class.forName(className,true,classLoader);
...
//找到SystemServer的main方法
m=cl.getMethod("main",new Class[]{String[].class});
...
// 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方法
throw new Zygote.MethodAndArgsCaller(m,argv);
}
在invokeStaticMain方法最后,以抛出异常的方式调用了SystemServer的main方法,(之后在启动其他应用进程的时候,也是这里调用ActivityThread的main方法的)。这种处理会清除所有设置过程需要的堆栈信息。
/**
* Helper exception class which holds a method and arguments and
* can call them. This is used as part of a trampoline to get rid of
* the initial process setup stack frames.
*/
public static class MethodAndArgsCaller extends Exception
implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
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);
}
}
}
这个功能比较单一,是协助反射调用的,调用了run方法将通过反射调用传入的方法。
接下来解析下SystemServer进程做了什么。
public static void main(String[] args){
//就一行代码
new SystemServer().run();
}
private void run(){
...
//创建消息Looper
Looper.prepareMainLooper();
//加载动态库
System.loadLibrary("android_servers");
//创建SystemServiceManager
mSystemServiceManager=new SystemServiceManager(mSystemContext);
...
//启动引导服务
startBootstrapServices();
//启动核心服务
startCoreServices();
//启动其他服务
startOtherServices();
...
}
在SystemServer进程中陆续启动了各种服务,包括ActivityManagerService、PowerManagerService、PackageManagerService等等,而这些服务的父类都是SystemService。
最后总结一下SystemServer进程:
- 启动Binder线程池。
- 创建了SystemServiceManager(用于对系统服务进行创建、启动和生命周期管理)。
- 启动了各种服务。