android系统的启动流程图

1.第一个系统进程--Init

Init是Android中第一个被启动的进程,init的PID为0,它主要的工作是解析init.rc()脚本来构建出系统的初始运行形态。init.rc可用于控制android系统启动状态。它在system/core/rootdir路经下。
Init解析启动的主要的系统进程

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server #启动zygote服务进程。Zygote是系统的“孵化器”,负责生产“进程”service servicemanager /system/bin/servicemanager #是Binder机制中“DNS服务器”,负责域名(某Binder服务在ServiceManager注册时提供的名称)到IP地址(由底层Binder驱动分配的值)的解析。service ueventd /sbin/ueventd #负责设备节点的创建、权限设定等一些列工作service adbd /sbin/adbd #adbd是android debug bridge daemon 的缩写,它为开发者与设备之间建立了一条通道srvice vold /system/bin/vold  #管理和控制Android平台外部存储设备,包括SD插拨、挂载、卸载、格式化等service debuggerd /system/bin/debuggerd #此进程可以侦测到程序崩溃,并将崩溃时的进程状态信息输出到文件和串口中,以供开发人员分析调试使用service media /system/bin/mediaserverservice drm /system/bin/drmserverservice ril-daemon /system/bin/rildservice keystore /system/bin/keystore /data/misc/keystore

2.“DNS服务器”--ServiceManager

ServiceManager是Binder机制中“DNS服务器”,负责域名(Binder在ServiceManager注册的名称)到IP地址(Binder Driver分配的值)的解析。
ServiceManager和Zygote一样是由Init进程启动的。在init.rc的脚本如下
service servicemanager /system/bin/servicemanager

3.Zygote进程孕育新进程

3.1.zygote的内部启动过程

3.1.1.zygote是第一个虚拟机进程

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
从zygote的解析脚本可以看出zygote是通过/system/bin/app_process来加载的,查看app_main.cpp源代码

int main(int argc, const char* const argv[]){    // These are global variables in ProcessState.cpp    mArgC = argc;    mArgV = argv;    mArgLen = 0;    for (int i=0; i<argc; i++) {        mArgLen += strlen(argv[i]) + 1;    }    mArgLen--;    AppRuntime runtime;   //...        while (i < argc) {        const char* 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;        }    }    if (niceName && *niceName) {        setArgv0(argv0, niceName);        set_process_name(niceName);    }    runtime.mParentDir = parentDir;    if (zygote) {//创建第一个虚拟机进程Zygote        runtime.start("com.android.internal.os.ZygoteInit",                startSystemServer ? "start-system-server" : "");    } else if (className) {        // Remainder of args get passed to startup class main()        runtime.mClassName = className;        runtime.mArgC = argc - i;        runtime.mArgV = argv + i;        runtime.start("com.android.internal.os.RuntimeInit",                application ? "application" : "tool");    } else {        fprintf(stderr, "Error: no class name or --zygote supplied.\n");        app_usage();        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");        return 10;    }}

从传入的–zygote –start-system-server参数可知,app_process接下来将通过AppRuntime.start启动虚拟机和调用ZygoteInit对应main()的并且传入“start-system-server”。其关键源码如下

/* * Start the Android runtime.  This involves starting the virtual machine * and calling the "static void main(String[] args)" method in the class * named by "className". * * Passes the main function two arguments, the class name and the specified * options string. */void AndroidRuntime::start(const char* className, const char* options){   //..    /* start the virtual machine */    JNIEnv* env;    if (startVm(&mJavaVM, &env) != 0) {        return;    }    onVmCreated(env);   //...}

因此可以知道Zygote是一个虚拟机进程。它是所有APK应用进程的父进程。

3.1.2.启动Socket服务

Zygote的Socket服务端口用于监听Client的Socket请求,孵化出新的应用进程。该LocalServerSocket是采用非阻塞模式,在runSelectLoop进入非阻塞读操作,首先将sServerSocket加入到被监测的文件描述符列表中,然后在while循环中将列表加入到select的列表中。

zygote虚拟机加载的第一个java类是ZygoteInit.java,它的入口main源码如下

public static void main(String argv[]) {        try {            //...            registerZygoteSocket(socketName);//注册Socket            //....            if (startSystemServer) {                startSystemServer(abiList, socketName);//启动SystemServer            }            preload();//预加载资源文件            Log.i(TAG, "Accepting command socket connections");            runSelectLoop(abiList); //非阻塞式监听            //...                }/** * Registers a server socket for zygote command connections * * @throws RuntimeException when open fails */    private static void registerZygoteSocket(String socketName) {        if (sServerSocket == null) {            int fileDesc;            final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;            try {                String env = System.getenv(fullSocketName);                fileDesc = Integer.parseInt(env);            } catch (RuntimeException ex) {                throw new RuntimeException(fullSocketName + " unset or invalid", ex);            }            try {                sServerSocket = new LocalServerSocket(                        createFileDescriptor(fileDesc));            } catch (IOException ex) {                throw new RuntimeException(                        "Error binding to local socket '" + fileDesc + "'", ex);            }        }    }     private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();        FileDescriptor[] fdArray = new FileDescriptor[4];        //将sServerSocket加入被监测的文件描述符列表中        fds.add(sServerSocket.getFileDescriptor());        peers.add(null);        int loopCount = GC_LOOP_COUNT;        while (true) {            int index;          //...            try {                //将该文件描述符添加到select的列表中                fdArray = fds.toArray(fdArray);                index = selectReadable(fdArray);            } catch (IOException ex) {                throw new RuntimeException("Error in select()", ex);            }            if (index < 0) {                throw new RuntimeException("Error in select()");            } else if (index == 0) {                ZygoteConnection newPeer = acceptCommandPeer(abiList);                peers.add(newPeer);                fds.add(newPeer.getFileDescriptor());            } else {                boolean done;                //调用ZygoteConnection类的runOnce函数处理一个Socket接收到的命令                done = peers.get(index).runOnce();                if (done) {                    peers.remove(index);                    fds.remove(index);                }            }        }    }    boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {            //...            //fork出一个子进程,即一个新的应用进程。              pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,                    parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,                    parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,                    parsedArgs.appDataDir);            checkTime(startTime, "zygoteConnection.runOnce: postForkAndSpecialize");      //...        try {            if (pid == 0) { //pid=0为子进程                // in child                IoUtils.closeQuietly(serverPipeFd);                serverPipeFd = null;                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);                // should never get here, the child is expected to either                // throw ZygoteInit.MethodAndArgsCaller or exec().                return true;            } else {                // in parent...pid of < 0 means failure                IoUtils.closeQuietly(childPipeFd);                childPipeFd = null;                return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);            }        } finally {            IoUtils.closeQuietly(childPipeFd);            IoUtils.closeQuietly(serverPipeFd);        }    }

3.1.3预装共享的Framework层的类

预装的Framework层的类的列表位于frameworks/base/preload-class,该文件通过frameworks/base/tools/preload/WritePreloadedClassFile.java来生成。preload-class文件默认情况下有2000多个类,加载后被所有的虚拟机进程共享。

android.app.ActionBarandroid.app.ActionBar$LayoutParamsandroid.app.Activityandroid.app.ActivityManagerandroid.app.ActivityManagerNativeandroid.app.ActivityManagerNative$1android.app.ActivityManagerProxyandroid.app.ActivityThreadandroid.app.ActivityThread$1android.app.ActivityThread$2android.app.ActivityThread$ActivityClientRecordandroid.app.ActivityThread$AppBindDataandroid.app.ActivityThread$ApplicationThreadandroid.app.ActivityThread$BindServiceDataandroid.app.ActivityThread$ContextCleanupInfoandroid.app.ActivityThread$CreateServiceDataandroid.app.ActivityThread$GcIdlerandroid.app.ActivityThread$Handroid.app.ActivityThread$Idlerandroid.app.ActivityThread$ProviderClientRecordandroid.app.ActivityThread$ProviderRefCount..........

加载这些类是由刚刚的ZygoteInit类中的preloadClasses方法完成。

    private static void preloadClasses() {        final VMRuntime runtime = VMRuntime.getRuntime();        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(                PRELOADED_CLASSES);        //...       //通过IO流的方式按行读取preload-class文件      //加载对应的类       while ((line = br.readLine()) != null) {                    // Skip comments and blank lines.                    line = line.trim();                    if (line.startsWith("#") || line.equals("")) {                        continue;                    }                    Class.forName(line);     }               //...   }

3.1.4.预装共享的Resource资源

资源文件位于frameworks/base/core/res/res中,由ZygoteInit类中的preloadResources方法分别调用preloadDrawalbe和preloadColorStateLists方法。加载后把这些资源放到全局变量mResources中,被所有的虚拟机进程共享。

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">    <!-- Do not translate. These are all of the drawable resources that should be preloaded by the zygote process before it starts forking application processes. -->    <array name="preloaded_drawables">       <item>@drawable/toast_frame</item>       <item>@drawable/btn_check_on_pressed_holo_light</item>       <item>@drawable/btn_check_on_pressed_holo_dark</item>       <item>@drawable/btn_check_on_holo_light</item>       <item>@drawable/btn_check_on_holo_dark</item>       <item>@drawable/btn_check_on_focused_holo_light</item>       <item>@drawable/btn_check_on_focused_holo_dark</item>       <item>@drawable/btn_check_on_disabled_holo_light</item>       <item>@drawable/btn_check_on_disabled_holo_dark</item>       <item>@drawable/btn_check_on_disabled_focused_holo_light</item>       <item>@drawable/btn_check_on_disabled_focused_holo_dark</item>       <item>@drawable/btn_check_off_pressed_holo_light</item>       <item>@drawable/btn_check_off_pressed_holo_dark</item>       <item>@drawable/btn_check_off_holo_light</item>       <item>@drawable/btn_check_off_holo_dark</item>       <item>@drawable/btn_check_off_focused_holo_light</item>       <item>@drawable/btn_check_off_focused_holo_dark</item>       <item>@drawable/btn_check_off_disabled_holo_light</item>       <item>@drawable/btn_check_off_disabled_holo_dark</item>       <item>@drawable/btn_check_off_disabled_focused_holo_light</item>       <item>@drawable/btn_check_off_disabled_focused_holo_dark</item>       <item>@drawable/btn_check_holo_light</item>       <item>@drawable/btn_check_holo_dark</item>       <item>@drawable/btn_radio_on_pressed_holo_light</item>       <item>@drawable/btn_radio_on_pressed_holo_dark</item>       <item>@drawable/btn_radio_on_holo_light</item>       <item>@drawable/btn_radio_on_holo_dark</item>      .....      .....

3.2.SystemServer进程

SystemServer进程是Zygote孵化出的第一个进程,由ZygoteInit.main调用startSystemServer()。startSystemServer关键源码

 private static boolean startSystemServer(String abiList, String socketName){     /* Hardcoded command line to start the system server */        String args[] = {            "--setuid=1000",            "--setgid=1000",            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007",            "--capabilities=" + capabilities + "," + capabilities,            "--runtime-init",            "--nice-name=system_server",            "com.android.server.SystemServer",        };        //孵化出SystemServer进程          pid = Zygote.forkSystemServer(                    parsedArgs.uid, parsedArgs.gid,                    parsedArgs.gids,                    parsedArgs.debugFlags,                    null,                    parsedArgs.permittedCapabilities,                    parsedArgs.effectiveCapabilities);       /* For child process */        if (pid == 0) {            handleSystemServerProcess(parsedArgs);        } }

3.2.1.SystemServer启动系统服务线程

SystemServer的main()方法调用run()方法,run()首先调用nativeInit()启动native层的service(SurfaceFlinger,AudioFliger等),然后调用startXXXService启动java层的service(ActivityManagerService,WindowManagerService,PackageManagerService等),源码如下

    /** * The main entry point from zygote. */    public static void main(String[] args) {        new SystemServer().run();    }    private void run() {        Looper.prepareMainLooper();        // Initialize native services.        nativeInit();         // Initialize the system context.        createSystemContext();        // Start services.        startBootstrapServices();        startCoreServices();        startOtherServices();        Looper.loop();    }

4.第一个activity

系统启动成功后SystemServer使用xxx.systemReady()通知各个服务,系统已经就绪,startOtherServices()调用ActivityManagerService.systemReady()方法,systemReady()最后一条语句调用了mStackSupervisor.resumeTopActivitiesLocked(),发出启动任务队列中最上面的Activity的消息。此时由于系统刚刚启动,所以调用了ActivityManagerService.startHomeActivityLocked()方法,然后发出一个Catagory字段包函android.intent.category.HOME的Intent,第一个activity启动,系统的Launcher和第三方程序都可以响应该Intent,源码如下。

    Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);        intent.setComponent(mTopComponent);        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {            intent.addCategory(Intent.CATEGORY_HOME);        }

启动的Activity为Launcher,路经在packages/apps/Launcher2/AndroidManifest.xml,源码如下。

        <activity  android:name="com.android.launcher2.Launcher" android:launchMode="singleTask" android:clearTaskOnLaunch="true" android:stateNotNeeded="true" android:theme="@style/Theme" android:windowSoftInputMode="adjustPan" android:screenOrientation="nosensor">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.HOME" />                <category android:name="android.intent.category.DEFAULT" />                <category android:name="android.intent.category.MONKEY"/>            </intent-filter>        </activity>

更多相关文章

  1. Android使用AIDL实现进程间的简单通信
  2. Android之Service总结
  3. 为什么Android要采用Binder作为IPC机制?
  4. Android中init进程的工作
  5. 深入解读Android的内部进程通信接口AIDL
  6. 给android系统添加自己想要的属性
  7. android settings--简述获取部分系统属性
  8. Android(安卓)退出Activity
  9. Android释放内存

随机推荐

  1. Mssql根据表名获取字段
  2. 这被认为是正常形式的失败吗?
  3. 建议一种有效的查询方式
  4. Code First for Mysql 错误:未为提供程序
  5. sql语句,order by后加参数问题
  6. mybatis中 insert into select 批量生成u
  7. ORA-19909:当进行不完全恢复之后使用open
  8. sql 2005判断某个表或某个表中的列是否存
  9. MySQL中的类Decode用法
  10. 如何优化用于从表复制数据的oracle过程?