Android启动流程


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传进来的参数,最重要的功能是由AppRuntimestart方法来完成。

2.1AppRuntime分析

AppRuntime类的声明和实现都在App_main.cpp中,是由AndroidRuntime类派生出来的,并且重载了onStartedonZygoteInitonExit函数。入口:

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函数——startRegJava世界用到的一些函数是采用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.ZygoteInitmain函数。

public static voidmain(String argv[]) {

            registerZygoteSocket();

            preload();

            if(argv[1].equals("start-system-server")) {

                startSystemServer();

            }

            if(ZYGOTE_FORK_MODE) {

                runForkMode();

            }else {

                runSelectLoopMode();

            }

            closeServerSocket();

    }

 

以上列出ZygoteInitmain函数几个重要的处理函数,其主要完成了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中建立的SocketselectReadable内部调用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.SystemServermain函数,这才是SystemServer的真面目:

publicstatic void main(String[] args) {

        ……

        //加载libandroid_servers.so

        System.loadLibrary("android_servers");

        //调用nativeinit1函数

        init1(args);

    }

其中main函数将加载libandroid_servers.so库,这个库所包含的源码文件在文件夹framwork/base/services/jni下。

Ø         init1分析

init1native函数,在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服务等,总之,系统各项重要的服务都在这里被启动。

客户端发送请求分析

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提供的,并非JDKProcess类,是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就会用ZygoteConnetionrunOnce函数处理数据:

[à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响应请求流程



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值