android启动--深入理解zygote
前一篇文章介绍了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处理流程讲解
更多相关文章
- 箭头函数的基础使用
- Python技巧匿名函数、回调函数和高阶函数
- Android获取CPU使用率的几种方式
- Activity的四种启动模式和onNewIntent()
- flutter包名,应用名称,图标,启动图片修改
- Android(安卓)彻底退出自己APP 并杀掉所有相关的进程
- Android(安卓)开机启动流程分析
- Android(安卓)monkey test 脚本的编写
- android中activity的启动方式