说说Android系统的启动流程

一、Android有哪些主要的系统进程?

通过init.rc系统配置文件可查看,大致内容如下:

/system/core/rootdir/init.rc

...
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
...
service surfaceflinger /system/bin/surfaceflinger
service servicemanager /system/bin/servicemanager
service media /system/bin/mediaserver
service keystore /system/bin/keystore /data/misc/keystore
...

从该配置文件中可以看到一些需要启动的系统服务,常用的Zygote、SurfaceFliger、ServiceManager等 ,特别注意SystemServer不在init.rc中,而是由zygote fork出来的。

二、这些系统进程是怎么启动的?

那么Zygote的启动是怎么启动的呢?

由上一篇Zygote的简单理解中可以知道,

1、Zygote实际上也是由Init进程fork出来

2、启动虚拟机,注册JNI函数,为接下来启动Java作准备

3、预期加载系统资源(常用类、主题资源、共享库等)

4、启动SystemServer

5、进入Socket Loop,在loop里面不断的接受loop消息,处理loop消息。那么这里是如何处理loop消息的呢?上一篇中已经有列举过,实际上是执行

com.android.internal.os.ZygoteConnection.java中的runOnce函数
boolean runOnce() {
    //跨进程传输过来的,如AMS,PMS等
    String[] args = readArgumentList();

    int pid = Zygote.forkAndSpecialize();
    
    if(pid == 0) {
        //in child,实际上是执行ActivityThread.main(),应用程序进程启动后,会调用ActivityThread.main()
        handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
        return true;
    } else {
        //父进程处理 
        return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
    }
}


private void handleChildProc(Arguments parsedArgs,...) {
    if (parsedArgs.runtimeInit) {
            if (parsedArgs.invokeWith != null) {
                //启动一些应用的初始化
                WrapperInit.execApplication(parsedArgs.invokeWith,
                        parsedArgs.niceName, parsedArgs.targetSdkVersion,
                        pipeFd, parsedArgs.remainingArgs);
            } else {
                //初始化ZygoteInit, 主要是加载一些Zygote的commonInit, nativeInit,AppliationInit
                RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
                        parsedArgs.remainingArgs);
            }
        } else {
            ...
            //通过ClassLoader去加载一些入口函数,比如SystemServer的main函数
            ZygoteInit.invokeStaticMain(cloader, className, mainArgs);
        }
}

那么SystemServer是如何启动的呢?

在com.android.internal.os.ZygoteInit.java中的main函数中启动SystemServer,启动函数如下

 /**
     * Prepare the arguments and fork for the system server process.
     */
    private static boolean startSystemServer() {
        ...
        /* Hardcoded command line to start the system server */
        String args[] = {..., "com.android.server.SystemServer"}; 
        ...
       ZygoteConnection.Arguments parsedArgs parsedArgs = new ZygoteConnection.Arguments(args);
          
         /* Request to fork the system server process */
         //从Zygote fork SystemServer进程
         int pid = Zygote.forkSystemServer(parseArgs.uid,...);

        /* For child process */
        if (pid == 0) {
            handleSystemServerProcess(parsedArgs);
        }
        return true;
    }

private static void handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
        ...
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
    }

public static final void zygoteInit(int targetSdkVersion, String[] argv) {
       
        commonInit();
        
        //主要用于启动binder机制,接下来的很多系统服务都需要用到binder机制,并且启动一个binder线程,很多系统服务都需要跟别的进程进行通信,比如Launcher启动的时候扫描已经安装的应用
        nativeZygoteInit();

        //调用java类的入口函数,实际上就是SystemServer.java的main函数
        applicationInit(targetSdkVersion, argv);
    }

public static void main(String[] args) {
        new SystemServer().run();
    }

private void run() {
        Looper.prepareMainLooper();

        // Initialize native services.
        System.loadLibrary("android_servers");

        //创建系统上下文,其实也可以看成是类似一个应用进程,也有自己的上下文
        createSystemContext();

        // Start services.
        startBootstrapServices();
        startCoreServices();
        startOtherServices();

        //进入主线程的loop循环
        Looper.loop();
    }

以上大致为SystemServer的启动流程,那么系统服务是怎么启动的?怎么解决系统服务之前的相互依赖?

系统服务怎么启动?

1、系统服务先发布,让应用程序可见,那么这个发布是执行什么样的过程呢?执行函数如下

在com.android.server.SystemService.java中

protected final void publishBinderService(String name, IBinder service,
            boolean allowIsolated, int dumpPriority) {
        //实际上是注册到ServiceManager中
        ServiceManager.addService(name, service, allowIsolated, dumpPriority);
    }

2、系统服务跑在什么线程?

实际上有些服务,如AMS,PMS跑在自己独立的工作线程,还有一些大家共用的工作线程,主要分为以下几大类

DisplayThread、FgThread(前台任务)、IoThread、UiThread。除此之外,还有binder线程,主要用于应用跨进程的调用。

 

怎么解决系统服务之前的相互依赖?

1、分批启动,对于一些比较基础的一些service放在前面一批启动,比如AMS,PMS,PKMS

2、分阶段启动,在每到相应阶段通知相应的Service,哪些资源可以使用了。

三、说说Android系统的启动流程?

主要流程

1、Zygote是如何启动的

2、SystemServer进程是怎么启动的

3、系统服务是怎么启动的

4、Launcher是如何启动

发布了11 篇原创文章 · 获赞 3 · 访问量 777

猜你喜欢

转载自blog.csdn.net/xj_hnust/article/details/97512355
今日推荐