前一篇文章介绍了init进程的启动过程,其中就有解析init.rc脚本,而根据其内容配置启动了很多重要的服务:Servicemanager和zygote进程就奠定了Android的基础,建立了真正的android空间。

进程名称进程路径

zygote /system/bin/app_process

servicemanager /system/bin/servicemanager

bootanim /system/bin/bootanimation

media /system/bin/mediaserver

...

这里还都是在native世界中,此层分析哪个service没有启动,则找到相关的进程加打印即可,比较好分析,成功启动的进程利用ps命令即可查看。

说明一下android中的两个不同世界:

JAVA世界:运行基于dalvik虚拟机的JAVA程序

NATIVE世界:利用C或C++开发的程序组成native世界。

下面开始分析zygote启动流程:

代码路径:frameworks\base\cmds\app_process

启动参数:

servicezygote/system/bin/app_process-Xzygote/system/bin--zygote--start-system-server

intmain(intargc,constchar*constargv[])

{

//TheseareglobalvariablesinProcessState.cpp

mArgC=argc;

mArgV=argv;

//Nextargisstartupclassnameor"--zygote"

if(i<argc){

arg=argv[i++];

if(0==strcmp("--zygote",arg)){//init.rc中的参数值

boolstartSystemServer=(i<argc)?

strcmp(argv[i],"--start-system-server")==0:false;

setArgv0(argv0,"zygote");

set_process_name("zygote");//利用prctl修改进程名称

runtime.start("com.android.internal.os.ZygoteInit",

startSystemServer);//这就是真正的重点!!!!

}

....

}

下面开始建立AndroidRuntime:

路径:frameworks\base\core\jni

classAppRuntime:publicAndroidRuntime

AppRuntime重载实现了onStarted(),onZygoteInit(),onExit()函数

runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);

-->调用

/*

*StarttheAndroidruntime.Thisinvolvesstartingthevirtualmachine

*andcallingthe"staticvoidmain(String[]args)"methodintheclass

*namedby"className".

*/

voidAndroidRuntime::start(constchar*className,constboolstartSystemServer)

{

//基本上再次看到这句话,说明系统重启了

LOGD("\n>>>>>>>>>>>>>>AndroidRuntimeSTART<<<<<<<<<<<<<<\n");


//1、启动虚拟机

/*startthevirtualmachine*/

if(startVm(&mJavaVM,&env)!=0)

gotobail;


//2、注册jni函数

/*

*Registerandroidfunctions.

*/

if(startReg(env)<0){

LOGE("Unabletoregisterallandroidnatives\n");

gotobail;

}

/*

3、从com.android.internal.os.ZygoteInit类中找到main函数,即调用

ZygoteInit.java类中的main,此时将进入到java世界。。。。

*/

startMeth=env->GetStaticMethodID(startClass,"main",

"([Ljava/lang/String;)V");

env->CallStaticVoidMethod(startClass,startMeth,strArray);

}


欢迎来到JAVA世界。。。。。

下面直接分析ZygoteInit类中的main函数:

路径:frameworks\base\core\java\com\android\internal\os

publicstaticvoidmain(Stringargv[]){

//1、建立端口号为50的监听套接字,用于接收

//ActivityManangerService的请求,Fork应用程序

registerZygoteSocket();

//2、预加载类和资源,优化代码时这里可以想点办法,不过有点麻烦

preloadClasses();

//3、垃圾回收

gc();

//4、启动SystemServer,这个下面再重点讲解

startSystemServer();

//5、处理客户连接与请求,具体由ZygoteConnection.runOnce()处理

runSelectLoopMode();

...

}


SystemServer的分析:

这个进程是由zygote产生的第一个进程

/**

*Preparetheargumentsandforkforthesystemserverprocess.

*/

privatestaticbooleanstartSystemServer()

{

...

/*Hardcodedcommandlinetostartthesystemserver*/

Stringargs[]={

"--setuid=1000",

"--setgid=1000","--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",

"--capabilities=130104352,130104352",

"--runtime-init",

"--nice-name=system_server",//processname

"com.android.server.SystemServer",//classname

};

//解析参数

parsedArgs=newZygoteConnection.Arguments(args);

/*Requesttoforkthesystemserverprocess*/

pid=Zygote.forkSystemServer(

parsedArgs.uid,parsedArgs.gid,

parsedArgs.gids,debugFlags,null);

/*Forchildprocess*/

if(pid==0){

handleSystemServerProcess(parsedArgs);//后面讲述

}

}

-->

forkSystemServer这是一个jni函数,调用:

\dalvik\vm\native\dalvik_system_Zygote.c下面

staticvoidDalvik_dalvik_system_Zygote_forkSystemServer(

constu4*args,JValue*pResult)

{

pid_tpid;

//根据参数fork出一个子进程,若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1

pid=forkAndSpecializeCommon(args);

if(pid>0) {

gDvm.systemServerPid=pid;

/*Thereisaslightwindowthatthesystemserverprocesshascrashed

*butitwentunnoticedbecausewehaven'tpublisheditspidyet.So

*werecheckherejusttomakesurethatalliswell.

*/

if(waitpid(pid,&status,WNOHANG)==pid){

LOGE("Systemserverprocess%dhasdied.RestartingZygote!",pid);

kill(getpid(),SIGKILL);

}

/*

这里表示SystemServer进程退出,而其父进程是Zygote,所以这里 kill掉的就是Zygote进程,即两者都退出了。。。。

*/

}

}


Zygote与SystemServer关系非常紧密,这里有个小处理逻辑:

staticpid_tforkAndSpecializeCommon(constu4*args)

{

setSignalHandler();

}

-->

staticvoidsetSignalHandler()

{

interr;

structsigactionsa;

memset(&sa,0,sizeof(sa));

sa.sa_handler=sigchldHandler;//在此安装了一个信号处理函数

err=sigaction(SIGCHLD,&sa,NULL);

...

}

信号处理函数:

/*

*Thissignalhandlerisforzygotemode,sincethezygote

*mustreapitschildren

*/

staticvoidsigchldHandler(ints)

{

pid_tpid;

while((pid=waitpid(-1,&status,WNOHANG))>0){

/*

*Ifthejust-crashedprocessisthesystem_server,bringdownzygote

*sothatitisrestartedbyinitandsystemserverwillberestarted

*fromthere.

*/

if(pid==gDvm.systemServerPid){

LOG(LOG_INFO,ZYGOTE_LOG_TAG,

"Exitzygotebecausesystemserver(%d)hasterminated\n",

(int)pid);

kill(getpid(),SIGKILL);

}

}

...

}


这里补充说明一下MethodAndArgsCaller 异常问题:

private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {

这里会抛出一个异常:MethodAndArgsCaller


那么肯定有地方接收这个异常:

还是在ZygoteInit.java

public static void main(String argv[]) {

try {

if (argv[1].equals("true")) {
startSystemServer();
}

.....

}catch (MethodAndArgsCaller caller) {
caller.run(); // 这里捕捉到startSystemServer异常
}

}


执行:

public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}

public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
}

处的mMethod为 com.android.server.SystemServer 的 main 函数 (SystemServer.java)

其实就是在这个抛出的异常中启动了 SystemServer 类,且这个异常为一个 Runnable 类型,因此

SystemServer 类就运行在 system_server 进程中的一个新的线程里。


Zygote启动流程内容太多,下一篇从handleSystemServerProcess处理流程讲解


更多相关文章

  1. 箭头函数的基础使用
  2. Python技巧匿名函数、回调函数和高阶函数
  3. Android获取CPU使用率的几种方式
  4. Activity的四种启动模式和onNewIntent()
  5. flutter包名,应用名称,图标,启动图片修改
  6. Android(安卓)彻底退出自己APP 并杀掉所有相关的进程
  7. Android(安卓)开机启动流程分析
  8. Android(安卓)monkey test 脚本的编写
  9. android中activity的启动方式

随机推荐

  1. eclipse开发android常见错误总结
  2. Android加密之全盘加密
  3. Android(安卓)高手进阶教程(十三)之----A
  4. Android应用开发提高系列(4)——Android动
  5. Android联系人数据库全解析(1)
  6. android状态机statemachine详解
  7. Android的nodpi,xhdpi,hdpi,mdpi,ldpi
  8. 如何设计一款AndroidAPP
  9. Android(安卓)中Activity,Window和View之
  10. Android(安卓)架构设计的思想与原则是什