android zygote进程到SystemServer进行的过程

1,430 阅读4分钟

「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战

android手机在启动时,会从rom中加载引导程序到ram中,然后初始化硬件参数等资源,然后会加载Linux内核到Ram中。Kernel接着会启动init祖先进程,在init进程中会解析init.rc等配置文件,接着就会开启zygote进程。

由于水平有限,先跳过Init进程解析init.rc的过程。直接看init进程中调用的app_main.cpp中main()函数

android 从init到zygote的过程 (1).png

下面是cpp_main.cpp的main函数。点击查看app_main.cpp的源码

源码基于android API 31 


int main(int argc, char* const argv[])
{
    //....省略部分代码

    // 可以看到下面这些变量是控制启动zygote,systemServer的标志
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    String8 niceName;
    String8 className;

    ++i;  // Skip unused "parent dir" argument.
    while (i < argc) {
        const char* arg = argv[i++];
        //比较进程名是否是“--zygote"
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        } 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.setTo(arg + 12);
        } else if (strncmp(arg, "--", 2) != 0) {
            className.setTo(arg);
            break;
        } else {
            --i;
            break;
        }
    }
    //......省略了部分代码 
  
    //主要流程。
    if (zygote) {
        //上面会对当前进程名比较是否是“--zygote",是则zygote = true,则会调用AndroidRuntime.start()
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
    //启动RuntimeInit
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    }
}

**可以看到main函数最后会调用androidRuntime的start方法。下面再分析androidRuntime的start方法 **

/*
 * 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 Vector<String8>& options, bool zygote)
{
  //......省略了部分代码 

    /* 启动虚拟机*/
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }
    onVmCreated(env);

    /*
     * Register android functions.
     */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    } 
    

    /*
    *根据'className'调用main函数(根据app_main.cpp中的main函数发现调用了RuntimeInit和ZygoteInit中的main函数)
     * Start VM.  This thread becomes the main thread of the VM, and will
     * not return until the VM exits.
     */
    char* slashClassName = toSlashClassName(className != NULL ? className : "");
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            env->CallStaticVoidMethod(startClass, startMeth, strArray);

#if 0
            if (env->ExceptionCheck())
                threadExitUncaughtException(env);
#endif
        }
    }

}


下面开始进入java类中ZygoteInit的main方法

public static void main(String argv[]) {
        ZygoteServer zygoteServer = new ZygoteServer();
        //......
        try {
            //......
            if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
               //......
            }
			//......
        } catch (Throwable ex) {
           //......
        } finally {
           //......
        }
		//......
    }
   }
}

从下面的方法可以看到,通过forkSystemServer方法来fork SystemServer进程:

private static Runnable forkSystemServer(String abiList, String socketName,
        ZygoteServer zygoteServer) {
   //......

    int pid;

    try {
        ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args);
        try {
      //.....
        pid = Zygote.forkSystemServer(
                parsedArgs.mUid, parsedArgs.mGid,
                parsedArgs.mGids,
                parsedArgs.mRuntimeFlags,
                null,
                parsedArgs.mPermittedCapabilities,
                parsedArgs.mEffectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }
//......

if (pid == 0) {
    if (hasSecondZygote(abiList)) {
        waitForSecondaryZygote(socketName);
    }

    zygoteServer.closeServerSocket();
    return handleSystemServerProcess(parsedArgs);
}

    return null;
}

下面是Zygote类中的forkSystemServer静态方法 
static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
        int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
    ZygoteHooks.preFork();
    //可以看到,在Zygote中通过调用JNI本地方法,fork出SystemServer进程
    int pid = nativeForkSystemServer(
            uid, gid, gids, runtimeFlags, rlimits,
            permittedCapabilities, effectiveCapabilities);
    //.....
    return pid;
}

在forkSystem最后一行代码可以发现在fork出子进程后,if (pid == 0)则执行handleSystemServerProcess(parsedArgs)

private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
        //......
        if (parsedArgs.invokeWith != null) {
            //......
        } else {
           //......
            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }
    }

紧跟着调用了ZygoteInit的zygoteInit方法:

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
        //......
        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }
// 接着调用  findStaticMain
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
        String[] argv, ClassLoader classLoader) {
  //.....
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

**//当前的className是SystemServer,所以接着通过JNI反射调用SystemServer的Main方法:
**protected static Runnable findStaticMain(String className, String[] argv,
        ClassLoader classLoader) {
    Class<?> cl;
//....

    return new MethodAndArgsCaller(m, argv);
}

下面再来看SystemServer的main方法

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

	public SystemServer() {
        // 检查工厂测试模式。
        mFactoryTestMode = FactoryTest.getMode();
        // Remember if it's runtime restart(when sys.boot_completed is already set) or reboot
        //记住,它是运行时重启(当sys.boot_completed已设置)还是重新引导
        mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));

        mRuntimeStartElapsedTime = SystemClock.elapsedRealtime();
        mRuntimeStartUptime = SystemClock.uptimeMillis();
    }
    
    
	private void run() {
        try {
         
            
            //如果设备时钟在1970之前,则重新赋值为1970
            if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
                SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
            }

            //如果没有设置时区,默认为格林威治时间(GMT)
            String timezoneProperty =  SystemProperties.get("persist.sys.timezone");
            if (timezoneProperty == null || timezoneProperty.isEmpty()) {
                SystemProperties.set("persist.sys.timezone", "GMT");
            }
            
            //检查设置语言环境
            if (!SystemProperties.get("persist.sys.language").isEmpty()) {
                final String languageTag = Locale.getDefault().toLanguageTag();

                SystemProperties.set("persist.sys.locale", languageTag);
                SystemProperties.set("persist.sys.language", "");
                SystemProperties.set("persist.sys.country", "");
                SystemProperties.set("persist.sys.localevar", "");
            }

            //系统服务器不应该进行非单向调用
            Binder.setWarnOnBlocking(true);
            //系统服务器应该始终加载安全标签
            PackageItemInfo.setForceSafeLabels(true);
            //停用SQLiteCompatibilityWalFlags,直到初始化设置提供程序
            SQLiteCompatibilityWalFlags.init(null);

            //----------此处开始进入Android系统服务-----------
            int uptimeMillis = (int) SystemClock.elapsedRealtime();
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
            if (!mRuntimeRestart) {
                MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);
            }

            //如果自上次引导以来运行时发生切换(例如什么时候)在OTA中删除旧的运行时),则设置系统属性,使其同步
            SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

            //更多内存
            VMRuntime.getRuntime().clearGrowthLimit();

            //系统服务器必须一直运行,因此需要尽可能高效地使用内存。
            VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

            //有些设备依赖于运行时指纹生成,因此在进一步引导之前请确保我们已经定义了它。
            Build.ensureFingerprintProperty();

            //在系统服务器中,在没有显式指定用户的情况下访问环境路径是错误的。
            Environment.setUserRequired(true);

            //在系统服务器中,任何传入的包都应该被解除锁定,以避免抛出BadParcelableException。
            BaseBundle.setShouldDefuse(true);

            //在系统服务器中,当打包异常时,包括堆栈跟踪
            Parcel.setStackTraceParceling(true);

            //确保对系统的绑定调用始终以前台优先级运行。
            BinderInternal.disableBackgroundScheduling(true);

            //增加system_server中绑定器线程的数量
            BinderInternal.setMaxThreads(sMaxBinderThreads);

            //准备创建主线程(当前线程).
            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);
            
            Looper.prepareMainLooper(); //创建主线程
            Looper.getMainLooper().setSlowLogThresholdMs(
                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

            //加载libandroid_servers.so库
            System.loadLibrary("android_servers");

            //检查我们上次试着关闭时是否失败
            performPendingShutdown();

            //初始化系统上下文
            createSystemContext();

            //创建SystemServiceManager
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

            //为可以并行化的init任务准备线程池
            SystemServerInitThreadPool.get();
        } finally {
            traceEnd();
        }

        //开启系统服务
        try {
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            throw ex;
        } finally {
            traceEnd();
        }

        //......
        
        //开启主线程,进入死循环,处理各种事件消息
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
    
	//此处稍微注意,全局上下文是通过ActivityThread创建的
	private void createSystemContext() {
        ActivityThread activityThread = ActivityThread.systemMain();
        mSystemContext = activityThread.getSystemContext();
        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

        final Context systemUiContext = activityThread.getSystemUiContext();
        systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
    }

以上的run方法大概可以分为下面几步:

首先设置时间、市区、语言等环境,然后设置虚拟机的一些属性参数 然后调用Looper.prepareMainLooper()创建主线程,即我们熟知的UI线程 接着加载android_servers底层库,初始化系统上下文对象 再接着就是初始化各种系统服务,例如:SystemServiceManager、ActivityServiceManager、WifiService等 最后调用Looper.loop()开启死循环,以处理各种事件消息 以上就是zygote进程到SystemServer进行的过程。