android zygote进程启动到SystemServer进程启动过程

首先,我们来看android手机启动过程图:
在这里插入图片描述

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

我们直接从启动zygote的函数出发,探究zygote进程的启动流程(跳过init进程的开启)。
PS:最精彩的在最后一段

1、首先init进程会运行app_main.cpp的main函数

点击查看app_main.cpp源文件

int main(int argc, char* const argv[]){
    //......
    bool zygote = false;
    //......省略了部分代码,期间会对当前进程名比较是否是“--zygote",是则zygote = true
    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        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.");
    }
}

可以看到,当zygote为true时,会执行:

runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
2、runtime是AppRuntime对象,接着我们看看runtime的strat函数:

点击查看AppRuntime.cpp源文件

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){
    //......
    
	//在startVm()函数中会开启java虚拟机
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);

    /*
     * 注册JNI函数
     */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }

    //......
    
    if (startClass == NULL) {
         //......
    } else {
    	//通过JNI反射ZygoteInit.java,并获取ZygoteInit的main方法
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",  "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
             //......
        } else {
        	//调用ZygoteInit的静态main方法
            env->CallStaticVoidMethod(startClass, startMeth, strArray); //调用ZygoteInit的静态main方法
		    //......
        }
    }
    //......
}
3、开始进入java的世界了,直接查看ZygoteInit的静态main方法

点击查看ZygoteInit.java

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) {
        //......
        try {
            //......
            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.runtimeFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            //......
        }
        //......
        
        /* For child process */
        if (pid == 0) {
            //......
            return handleSystemServerProcess(parsedArgs);
        }
        return null;
    }
4、接着先查看Zygote的forkSystemServer方法

点击查看Zygote.java源文件

public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
        //......
        int pid = nativeForkSystemServer(
                uid, gid, gids, runtimeFlags, rlimits, permittedCapabilities, effectiveCapabilities);
       //......
        return pid;
    }
    
native private static int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);

可以看到,在Zygote中通过调用JNI本地方法,fork出SystemServer进程。

5、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);
    }
6、再来看RuntimeInit.java的applicationInit方法
	protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
        // .....
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }


	protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
        //......
        Method m;
        try {
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
           //......
        } catch (SecurityException ex) {
            //......
        }
        //......
        return new MethodAndArgsCaller(m, argv);
    }

当前的className是SystemServer,所以接着通过JNI反射调用SystemServer的Main方法:

7、再来看SystemServer.java的main方法

点击查看SystemServer.java源文件

	/**
     * zygote的主入口点.
     */
    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();
    }
8、现在主要来看SystemServer.java的run方法

这个run()方法非常重要,可以说是android系统运行的核心了,因为在这里会设置设备的时间、语言、区域等环境,主线程也在其中开启,还有一坨坨的系统服务器也是在这里开启的。

	private void run() {
        try {
        	//开启日志跟踪
            traceBeginAndSlog("InitBeforeStartServices");  
            
            //如果设备时钟在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进行的过程。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值