AOSP 8.0 系统启动之五systemserver启动(二)

目录​​​​​​​

前言

一、systemserver开始工作

1.1 ZygoteInit.handleSystemServerProcess

1.1.1 ZygoteInit.performSystemServerDexOpt

1.1.2  ZygoteInit.createPathClassLoader

1.2 ZygoteInit.zygoteInit

1.2.1 RuntimeInit.commonInit

1.2.2 ZygoteInit.nativeZygoteInit

1.2.3 RuntimeInit.applicationInit()

1.2.4 RuntimeInit.invokeStaticMain


前言

        上一篇文章已经将systemserver进程创建出来,接下去重点分析下剩余的主要逻辑;

        涉及源码

/frameworks/base/core/java/com/android/internal/os/
  - ZygoteInit.java
  - RuntimeInit.java
  - Zygote.java

/frameworks/base/core/services/java/com/android/server/
  - SystemServer.java

/frameworks/base/core/jni/
  - com_android_internal_os_Zygote.cpp
  - AndroidRuntime.cpp

/frameworks/base/cmds/app_process/App_main.cpp

一、systemserver开始工作

1.1 ZygoteInit.handleSystemServerProcess

public class ZygoteInit {
    private static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) {
        xxxx
        /* For child process */
        if (pid == 0) {
            //有两个zygote进程情况,需等待第2个zygote创建完成。
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
        
            zygoteServer.closeServerSocket(); //需要关闭zygote原有的socke
            return handleSystemServerProcess(parsedArgs);  //
        }
    }
    
    //system_server进程已经创建ok,进而继续调用systemServer.main函数
    private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
        //设置当前进程名称
        if (parsedArgs.niceName != null) {
            Process.setArgV0(parsedArgs.niceName);
        }
        
        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
        // $SYSTEMSERVERCLASSPATH                                         
        // /system/bin/sh: /system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar:/system/framework/dframework.jar: not found
        if (systemServerClasspath != null) {
            //调用installd 将jar->dex->odex
    	    performSystemServerDexOpt(systemServerClasspath);
        }
    
        if (parsedArgs.invokeWith != null) { //不走这个分支
            .....
        } else {
            ClassLoader cl = null;
            if (systemServerClasspath != null) {
                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
                Thread.currentThread().setContextClassLoader(cl);  //当前system_server主线程设置classloader
            }
            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }

    }
    
}

1.1.1 ZygoteInit.performSystemServerDexOpt

将classPath字符串中的jar,分别进行dex优化操作。真正执行优化工作通过socket通信将相应的命令参数,发送给installd来完成。

//参数 : /system/framework/目录下的services.jar,ethernet-service.jar,wifi-service.jar
// $SYSTEMSERVERCLASSPATH                                         
// /system/bin/sh: /system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar:/system/framework/dframework.jar: not found
private static void performSystemServerDexOpt(String classPath) {
    final String[] classPathElements = classPath.split(":");
    //创建一个与installd的建立socket连接
    final InstallerConnection installer = new InstallerConnection();
    //执行ping操作,直到与installd服务端连通为止
    installer.waitForConnection();
    final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();

    try {
        for (String classPathElement : classPathElements) {
            final int dexoptNeeded = DexFile.getDexOptNeeded(
                    classPathElement, "*", instructionSet, false /* defer */);
            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                //以system权限,执行dex文件优化
                installer.dexopt(classPathElement, Process.SYSTEM_UID, false,
                        instructionSet, dexoptNeeded);
            }
        }
    } catch (IOException ioe) {
        throw new RuntimeException("Error starting system_server", ioe);
    } finally {
        installer.disconnect(); //断开与installd的socket连接
    }
}

1.1.2  ZygoteInit.createPathClassLoader

第一次见到了Java世界的类加载器

static PathClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
  //通过命令行获取为空
  //root@xxx:/ # getprop java.library.path

  //root@xxx:/ # 
  String libraryPath = System.getProperty("java.library.path"); 

  return PathClassLoaderFactory.createClassLoader(classPath,
                                                  libraryPath,
                                                  libraryPath,
                                              ClassLoader.getSystemClassLoader(),
                                                  targetSdkVersion,
                                                  true /* isNamespaceShared */);
}
 

1.2 ZygoteInit.zygoteInit

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {

        RuntimeInit.commonInit(); //设置初始的错误异常设置
        ZygoteInit.nativeZygoteInit();  //主要是用来启动一个Binder线程池这样SystemServer进程就可以与其他进程进行通信了,zygote进程没有bidner
        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);  //见下文分析,启动SystemServer.main 函数
    }

1.2.1 RuntimeInit.commonInit

private static final void commonInit() {
    
    Thread.setUncaughtExceptionPreHandler(new LoggingHandler());
    // 设置默认的未捕捉异常处理方法, system_server 线程异常的时候,处理函数一般是释放资源,杀当前进程
    Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler());

    
    initialized = true;
}

1.2.2 ZygoteInit.nativeZygoteInit

/*framework/base/core/jni/AndroidRuntime.cpp*/
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz) {
    //此处的gCurRuntime为AppRuntime,是在AndroidRuntime.cpp中定义的
    gCurRuntime->onZygoteInit();
}


/*framework/base/cmds/app_process_app_main.cpp*/
virtual void onZygoteInit() {
    sp<ProcessState> proc = ProcessState::self();
    proc->startThreadPool(); //启动新binder线程, 关于binder线程的介绍,后续专题介绍
}

终于也见到了binder 机制的部分,zygote 进程中咩有binder相关内容,ProcessState::self()是单例模式,进程唯一,其构造函数中的主要工作是调用open()打开/dev/binder驱动设备,再利用mmap()映射内核的地址空间,将Binder驱动的fd赋值ProcessState对象中的变量mDriverFD,用于跨进程RPC交互操作。startThreadPool()是创建一个新的binder线程,不断进行talkWithDriver(),写入parcel数据,以及读parcel数据。

1.2.3 RuntimeInit.applicationInit()

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    //true代表应用程序退出时不调用AppRuntime.onExit(),否则会在退出前调用
    nativeSetExitWithoutCleanup(true);

    //设置虚拟机的内存利用率参数值为0.75
    VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
    VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

    final Arguments args;
    try {
        args = new Arguments(argv); //解析参数,最重要的就是args.startClass值
    } catch (IllegalArgumentException ex) {
        return;
    }

    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

    //说明:通过参数解析,得到args.startClass = com.android.server.SystemServer
    // Remaining arguments are passed to the start class's static main
    //调用startClass的static方法 main()
    invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

1.2.4 RuntimeInit.invokeStaticMain

利用反射机制可以得到SystemServer类,并找到SystemServer中的 main方法,然后将找到的 main方法传入到MethodAndArgsCaller异常中并抛出该异常,而捕获MethodAndArgsCaller异常的代码在Zygotelnit.java的 main方法中

//RuntimeInit.java
private static void invokeStaticMain(String className, String[] argv, ClassLoader     classLoader) throws ZygoteInit.MethodAndArgsCaller {
    cl = Class.forName(className, true, classLoader);
    Method  m = cl.getMethod("main", new Class[] { String[].class });
    throw new ZygoteInit.MethodAndArgsCaller(m, argv);   .....最后进入到ZygoteIint
}


public static class MethodAndArgsCaller extends Exception implements Runnable {
    public void run() {
        mMethod.invoke(null, new Object[] { mArgs });  // 进入到SystemServer的main 方法;
    }
}

至此,终于是进入到了SystemServer类的main()方法,其中几个核心服务了,下篇继续分析;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值