1启动流程图
2Android启动类图

3init.rc初始化
service zygote/system/bin/app_process -Xzygote /system/bin --zygote--start-system-server
classmain
socketzygote stream 666
onrestartwrite /sys/android_power/request_state wake
onrestartwrite /sys/power/state on
onrestartrestart media
onrestartrestart netd
|
以上是在init.rc中定义了一个名称为zygote的服务,首先第一行中使用service指令告诉操作系统将zygote程序加入到系统服务中,service的语法如下:
service service_name 可执行程序的路径 可执行程序自身所需的参数列表
|
此处的服务被定义为zygote,理论上讲该服务的名称可以是任意的。可执行程序的路径正是/system/bin/app_process,参数一共包含四个,分别如下:
Ø -Xzygote,该参数将作为虚拟机启动时所需要的参数,是在AndroidRuntime.cpp类的startVm()函数中调用JNI_CreateJavaVM()时被使用的。
Ø /system/bin,代表虚拟机程序所在目录,因为app_process完全可以不和虚拟机在同一个目录,而在app_process内部的AndroidRuntime类内部需要知道虚拟机所在的目录。
Ø --zygote,指明以ZygoteInit类作为虚拟机执行的入口,如果没有--zygote参数,则需要明确指定需要执行的类名。
Ø --start-system-server,仅在指定--zygote参数时才有效,意思是告知ZygoteInit启动完毕后孵化出第一个进程SystemServer。
接下来的配置命令socket用于指定该服务所使用到的socket,后面的参数依次是名称、类型、端口地址。onrestart命令指定该服务重启的条件,即当满足这些条件后,zygote服务就需要重启,这些条件一般是一些系统异常条件。
System/core/init/init.c里定义了一个main函数,是android启动的入口,之后解析init.rc中定义的服务
4 zygote分析
Zygote本身是一个Native应用程序,根据上一节可知,它是由Init进程根据init.rc文件中的配置项来创建的。
程序入口:frameworks/base/cmds/app_process/app_main.cpp
int main(int argc,const char* const argv[])
{
while(i < argc) {
constchar* arg = argv[i++];
if(!parentDir) {
parentDir= arg;
}else if (strcmp(arg, "--zygote") == 0) {
zygote= true;
niceName= "zygote";
}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= arg + 12;
}else {
className= arg;
break;
}
}
runtime.mParentDir= parentDir;
if(zygote) {
runtime.start("com.android.internal.os.ZygoteInit",start-system-server);
}
|
这个main函数主要是解析init.rc传进来的参数,最重要的功能是由AppRuntime的start方法来完成。
2.1AppRuntime分析
AppRuntime类的声明和实现都在App_main.cpp中,是由AndroidRuntime类派生出来的,并且重载了onStarted、onZygoteInit和onExit函数。入口:
AndroidRuntime.start("com.android.internal.os.ZygoteInit","start-system-server")
voidAndroidRuntime::start(const char* className, const char*options)
{ //创建虚拟机
JNIEnv*env;
if(startVm(&mJavaVM,&env) != 0) {
return;
}
//注册JNI函数
if (startReg(env) <0) {
LOGE("Unableto register all android natives\n");
return;
}
…….
char* slashClassName =toSlashClassName(className);
jclassstartClass =env->FindClass(slashClassName);
if(startClass == NULL) {
LOGE("JavaVMunable to locate class '%s'\n", slashClassName);
}else {
jmethodIDstartMeth = env->GetStaticMethodID(startClass,"main",
"([Ljava/lang/String;)V");
if(startMeth == NULL) {
LOGE("JavaVMunable to find main() in '%s'\n", className);
}else {
env->CallStaticVoidMethod(startClass,startMeth, strArray);
}
}
}
|
通过以上代码分析,AndroidRuntime.start()方法主要是为了进入java世界做准备,分为三件事情:
Ø 创建虚拟机——startVm。调用JNI的虚拟机创建函数,其参数都是在startVm中确定的。
Ø 注册JNI函数——startReg。Java世界用到的一些函数是采用native方式实现的,所以需要给虚拟机注册这些函数。
Ø 进入java世界的入口。调用env->CallStaticVoidMethod(startClass,startMeth,
strArray)进入java世界,这个JNI调用的意义是,调用com.android.internal.os.ZygoteInit java类的main函数,传递的参数是
“com.android.internal.os.ZygoteInit start-system-server”。
2.2java 世界
由上一小节可知,CallStaticVoidMethod最终调用com.android.internal.os.ZygoteInit的main函数。
public static voidmain(String argv[]) {
registerZygoteSocket();
preload();
if(argv[1].equals("start-system-server")) {
startSystemServer();
}
if(ZYGOTE_FORK_MODE) {
runForkMode();
}else {
runSelectLoopMode();
}
closeServerSocket();
}
|
以上列出ZygoteInit类main函数几个重要的处理函数,其主要完成了4大关键点:
1、 注册Socket服务端——registerZygoteSocket
private static voidregisterZygoteSocket() {
if(sServerSocket == null) {
intfileDesc;
try{
Stringenv = System.getenv(ANDROID_SOCKET_ENV);
fileDesc= Integer.parseInt(env);
}catch (RuntimeException ex) {
thrownew RuntimeException(
ANDROID_SOCKET_ENV+ " unset or invalid", ex);
}
try{
sServerSocket= new LocalServerSocket(
createFileDescriptor(fileDesc));
}catch (IOException ex) {
thrownew RuntimeException(
"Errorbinding to local socket '" + fileDesc + "'", ex);
}
}
}
|
Zygote及系统中其他程序的通信没有使用Binder通信,而是采用了基于AF_UNIX类型的Socket通信,以上代码就是注册Socket通信的服务端,用于监听客户端发过来的消息。
2、 预加载类和资源
Preload()方法完成预加载类和资源,其中调用preloadClassed()预加载类,调用preloadResources预加载资源。
Ø preloadClassed
在frameworks/base目录中有一个名为“preloaded-classes”的文件,罗列出所有需要加载的类,是有framework/base/tools/preload工具生成的。
Ø preloadResources
主要加载framework-res.apk中的资源。
3、 启动system_server进程
private static booleanstartSystemServer()
throwsMethodAndArgsCaller, RuntimeException {
intpid;
try{
pid= Zygote.forkSystemServer(
parsedArgs.uid,parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
}catch (IllegalArgumentException ex) {
thrownew RuntimeException(ex);
}
if(pid == 0) {
handleSystemServerProcess(parsedArgs);
}
returntrue;
}
|
这里创建了java世界中系统service所在的进程system_server,该进程是framework的核心,如果它死了,就会导致zygote自杀。通过调用Zygote.forkSystemServer这个函数创建出system_server进程,其工作是在handleSystemServerProcess(parsedArgs)方法中。
4、 等待客户端请求——runSelectLoopMode
private static voidrunSelectLoopMode() throws MethodAndArgsCaller {
while(true) {
fds.add(sServerSocket.getFileDescriptor());
try{
fdArray= fds.toArray(fdArray);
index= selectReadable(fdArray);
}catch (IOException ex) {
thrownew RuntimeException("Error in select()", ex);
}
if(index < 0) {
thrownew RuntimeException("Error in select()");
}else if (index == 0) {
ZygoteConnectionnewPeer = acceptCommandPeer();
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
}else {
booleandone= peers.get(index).runOnce();
}
}
}
|
sServerSocket是第1点中在registerZygoteSocket中建立的Socket,selectReadable内部调用select,当客户端连接或有数据时,selectReadable就会有返回。客户端在Zygote的代表是ZygoteConnection,当有一个客户端连接上的时候index==0,当客户端发送请求的时候,index>0,后续处理由ZygoteConnection.runOnce()完成.
5SystemServer分析
5.1SystemServer的创建
由第二节介绍可知,在ZygoteInit中调用native函数Zygote.forkSystemServer()创建的的进程。
5.2SystemServer的工作
SystemServer创建后,就与Zygote区分开来,有了自己的使命:
pid=Zygote.forkSystemServer()
if (pid == 0){
handleSystemServerProcess(parsedArgs);
}
|
调用handleSystemServerProcess来完成自己的工作。
privatestatic void handleSystemServerProcess(
ZygoteConnection.ArgumentsparsedArgs)
throwsZygoteInit.MethodAndArgsCaller {
closeServerSocket();
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,parsedArgs.remainingArgs);
}
}
|
调用closeServerSocket()关闭从Zygote那里继承下来的Socket,接着调用RuntimeInit.zygoteInit,再接着调用RuntimeInit.invokeStaticMain方法去调用com.android.server.SystemServer的main函数,这才是SystemServer的真面目:
publicstatic void main(String[] args) {
……
//加载libandroid_servers.so库
System.loadLibrary("android_servers");
//调用native的init1函数
init1(args);
}
|
其中main函数将加载libandroid_servers.so库,这个库所包含的源码文件在文件夹framwork/base/services/jni下。
Ø init1分析
init1是native函数,在com_android_server_SystemServer.cpp中实现,其主要工作是创建一些系统服务,然后把调用线程加入到Binder通信中。期间还通过JNI调用了com.android.server.SystemServer类中的init2函数。
Ø init2分析
publicstatic final void init2() {
Threadthr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
|
启动了一个serverThread线程,用以启动系统各项重要服务,例如启动电源管理服务、电池管理服务、windowManager服务、ActivityManager服务等,总之,系统各项重要的服务都在这里被启动。
6 客户端发送请求分析
Zygote创建出system_server后,就通过runSelectLoopMode等待并处理来自客户端的消息。我们以创建一个Activity的启动为例,具体分析Zygote是如何分裂和繁殖的。
6.1ActivityManagerService发送请求
ActivityManagerService是由System_server创建的。假设通过startActivity来启动一个新的Activity,并且它不属于一个未启动的进程,从ActivityManagerService中的startProcessLocked函数看,代码如下所示:
[àActivityManagerService.java]
privatefinal void startProcessLocked(ProcessRecord app,
StringhostingType, String hostingNameStr) {
……
Process.ProcessStartResult startResult =Process.start("android.app.ActivityThread",
app.processName,uid, uid, gids, debugFlags,
app.info.targetSdkVersion,null);
…….
}
|
Process类是android提供的,并非JDK的Process类,是android.os.Process,start函数代码如下:
[àProcess.java]
publicstatic final ProcessStartResult start(final StringprocessClass,
finalString niceName,
intuid, int gid, int[] gids,
intdebugFlags, int targetSdkVersion,
String[]zygoteArgs) {
return startViaZygote(processClass,niceName, uid, gid, gids,
debugFlags,targetSdkVersion, zygoteArgs);
…..
}
|
[àProcess.java::startViaZygote()]
privatestatic ProcessStartResult startViaZygote(final StringprocessClass,
finalString niceName,
finalint uid, final int gid,
finalint[] gids,
intdebugFlags, int targetSdkVersion,
String[]extraArgs)
throwsZygoteStartFailedEx {
argsForZygote.add("--runtime-init");//一些参数设置
argsForZygote.add("--setuid="+ uid);
argsForZygote.add("--setgid="+ gid);
……
return zygoteSendArgsAndGetResult(argsForZygote);
}
}
|
[àProcess.java:: zygoteSendArgsAndGetResult()]
privatestatic ProcessStartResultzygoteSendArgsAndGetResult(ArrayList<String>args)
throwsZygoteStartFailedEx {
//打开与Zygote通信的Socket
openZygoteSocketIfNeeded();
//把请求参数发送到Zygote
sZygoteWriter.write(Integer.toString(args.size()));
sZygoteWriter.newLine();
……
sZygoteWriter.write(arg);
sZygoteWriter.newLine();
}
//等待Zygote处理结束,获取创建进程的pid
sZygoteWriter.flush();
ProcessStartResultresult = new ProcessStartResult();
result.pid= sZygoteInputStream.readInt();
if(result.pid < 0) {
thrownew ZygoteStartFailedEx("fork() failed");
}
result.usingWrapper= sZygoteInputStream.readBoolean();
returnresult;
}
|
6.2响应客户端请求
[àZygoteInit.java:: runSelectLoopMode()]
private static voidrunSelectLoopMode() throws MethodAndArgsCaller {
while(true) {
fds.add(sServerSocket.getFileDescriptor());
try{
fdArray= fds.toArray(fdArray);
index= selectReadable(fdArray);
}catch (IOException ex) {
thrownew RuntimeException("Error in select()", ex);
}
}else if (index == 0) {
ZygoteConnectionnewPeer = acceptCommandPeer();
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
}else {
booleandone= peers.get(index).runOnce();
}
}
}
|
每当有请求数据发来,Zygote就会用ZygoteConnetion的runOnce函数处理数据:
[àZygoteConnetion.java:: runOnce()]
booleanrunOnce() throws ZygoteInit.MethodAndArgsCaller {
args= readArgumentList();
descriptors= mSocket.getAncillaryFileDescriptors();
…..
parsedArgs= new Arguments(args);
…..
pid= Zygote.forkAndSpecialize(parsedArgs.uid,parsedArgs.gid,
parsedArgs.gids,parsedArgs.debugFlags, rlimits);
…..
if(pid == 0) {
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd= null;
handleChildProc(parsedArgs,descriptors, childPipeFd, newStderr);
returntrue;
}else {
returnhandleParentProc(pid, descriptors, serverPipeFd,parsedArgs);
}
}
|
调用readArgumentList()读取System_server发送过来的参数,然后调用Zygote.forkAndSpecialize()创一个子进程,接着调用handleChidProc进行子进程的处理,其实就是要创建Activity对应的子进程。
[àZygoteConnetion.java:: handleChildProc()]
privatevoid handleChildProc(Arguments parsedArgs,
FileDescriptor[]descriptors, FileDescriptor pipeFd, PrintStreamnewStderr)
throwsZygoteInit.MethodAndArgsCaller {
if (parsedArgs.runtimeInit) {
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs);
}
}
|
RuntimeInit.zygoteInit()大家应该熟悉了,在创建System_server的时候用到。这里也一样,调用RuntimeInit.zygoteInit()之后,再调用RuntimeInit.
invokeStaticMain去执行android.app.ActivityThread类的main函数,这也就是apk程序对应的main函数。
6.3Zygote响应请求流程