android zygote进程启动流程

 Android系统启动篇

1,《android系统启动流程简介》

2,《android init进程启动流程》

3,《android zygote进程启动流程》

4,《Android SystemServer进程启动流程》

5,《android launcher启动流程》

6,《Android Activity启动过程详解》

Android系统开发准备篇

1,《Android 源码下载和编译》

2,《android 11源码编译和pixel3 刷机》

3,《Android Framework代码IDE加载和调试》

Android系统开发实践篇

1,《android设置默认输入法》

2,《android framework预制APK应用》

3,《Android系统层面限制应用开机自启动详解》

4,《android单独编译framework模块并push》

5,《Android Framework开发系统问题分析》

Android系统开发核心知识储备篇

1,《Android编译系统-envsetup和lunch代码篇》

2,《Android编译系统-概念篇》

3,《android日志系统详解》

4,《Android系统Handler详解》

5,《Android系统Binder详解》

6,《Android中Activity、View和Window关系详解》

7,《android view绘制流程详解》

8,《Android读取系统属性详解》

9,《android 窗口管理机制详解》

10,《初识Android系统》

11,《android中AMS进程通知Zygote进程fork新进程的通信方式》

Android核心功能详解篇

1,《android应用市场点击下载APK安装详解》

2,《Android 手势导航(从下往上滑动进入多任务页面)》

3,《android手势分析(应用界面左往右边滑动退出应用)》

4,《android应用安装流程详解》

5,《android11安装应用触发桌面图标刷新流程》

6,《Android系统多任务Recents详解》

7,《android系统导航栏视图分析》

———————————————————————————————————————————

目录

一,背景介绍

二,启动流程

2.1  启动入口

2.2 AndroidRuntime

2.3 Zygoteinit

2.4 启动SystemServer


一,背景介绍

        Init进程启动后,最重要的一个进程就是Zygote进程,SystemServer和其他所有Dalivik虚拟机进程都是由Zygote fork而来。Zygote进程由app_process启动,Zygote是一个C/S模型,Zygote进程作为服务端,其他进程作为客户端向它发出“孵化-fork”请求,而Zygote接收到这个请求后就“孵化-fork”出一个新的进程。由于Zygote进程在启动时会创建Java虚拟机,因此通过fork而创建的应用程序进程和SystemServer进程可以在内部获取一个Java虚拟机的实例拷贝。

       在system/core/rootdir/init.zygote64.rc文件中,启动zygote进程如下,

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server

init进程就是通过这个service名称来创建zygote进程,zygote这个服务,通过执行进行/system/bin/app_process64 并传入4个参数进行运行,创建一个子进程,参数说明如下,

1,-Xzygote 该参数将作为虚拟机启动时所需的参数
2,/system/bin 代表虚拟机程序所在目录
3,--zygote 指明以ZygoteInit.java类中的main函数作为虚拟机执行入口
4,--start-system-server 告诉Zygote进程启动systemServer进程

二,启动流程

2.1  启动入口

  路径:frameworks/base/cmds/app_process/app_main.cpp

int main(int argc, char* const argv[])
{
---------------------------------------------------------------
	 //zygote传入的参数argv为“-Xzygote /system/bin --zygote --start-system-server --socket-name=zygote”
	 //zygote_secondary传入的参数argv为“-Xzygote /system/bin --zygote --socket-name=zygote_secondary”
	...
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
			 //是否需要启动system server
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
			//启动进入独立的程序模式
            application = true;
        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
			//niceName 为当前进程别名,区别abi型号
            niceName.setTo(arg + 12);
        } else if (strncmp(arg, "--", 2) != 0) {
            className.setTo(arg);
            break;
        } else {
            --i;
            break;
        }
    }
	..
	if (!className.isEmpty()) { //className不为空,说明是application启动模式
		...
	} else {
	  //进入zygote模式,新建Dalvik的缓存目录:/data/dalvik-cache
        maybeCreateDalvikCache();
		if (startSystemServer) { //加入start-system-server参数
            args.add(String8("start-system-server"));
        }
		String8 abiFlag("--abi-list=");
		abiFlag.append(prop);
		args.add(abiFlag);	//加入--abi-list=参数
		// In zygote mode, pass all remaining arguments to the zygote
		// main() method.
		for (; i < argc; ++i) {	//将剩下的参数加入args
			args.add(String8(argv[i]));
		}
	}
	...
    if (!niceName.isEmpty()) {
        runtime.setArgv0(niceName.string(), true /* setProcName */);
    }
    if (zygote) {	 //如果是zygote启动模式,则加载ZygoteInit
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {	//如果是application启动模式,则加载RuntimeInit
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
		//没有指定类名或zygote,参数错误
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    }
------------------------------------------------
}

首先是解析传入的启动参数,根据--zygote参数,来确认执行那个方法,这里有两种情况

1,执行ZygoteInit,也就是去初始化zygote进程
2,执行RuntimeInit,这里其实就是启动普通应用程序

我们现在是初次启动,会走入第一个分支,也就是去执行ZygoteInit,可以看到,这里是通过runtime变量去调用start方法,实际上调用的是其父类AndroidRuntime的start方法

2.2 AndroidRuntime

路径:frameworks/base/core/jni/AndroidRuntime.cpp

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    ALOGD(">>>>>> START %s uid %d <<<<<<\n",
            className != NULL ? className : "(unknown)", getuid());

    static const String8 startSystemServer("start-system-server");

    //判断是否是启动systemServer
    for (size_t i = 0; i < options.size(); ++i) {
        if (options[i] == startSystemServer) {
           /* track our progress through the boot sequence */
           const int LOG_BOOT_PROGRESS_START = 3000;
           LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,  ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
        }
    }
    //从环境变量ANDROID_ROOT中读取系统目录
    const char* rootDir = getenv("ANDROID_ROOT");
    if (rootDir == NULL) {
        rootDir = "/system";
        if (!hasDir("/system")) {
            LOG_FATAL("No root directory specified, and /android does not exist.");
            return;
        }
        setenv("ANDROID_ROOT", rootDir, 1);
    }

    //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
    //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);

    /* start the virtual machine */
    JniInvocation jni_invocation;
    //初始化jni接口
    jni_invocation.Init(NULL);
    JNIEnv* env;
    //启动虚拟机
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    //这里实际上调用的子类的重写方法,也就是前面app_main.cpp中的AppRuntime
    onVmCreated(env);

    //...省略以下代码,主要去调用上面的java方法Zygoteinit
}

整体来看,经历了以下几个步骤

1,判断是否启动SystemSever

2,从环境变量ANDROID_ROOT中读取系统目录

3,初始化jni接口,并启动虚拟机

4,启动Zygoteinit类的main()函数

2.3 Zygoteinit

路径:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

    public static void main(String argv[]) {
        ZygoteServer zygoteServer = new ZygoteServer();

        // Mark zygote start. This ensures that thread creation will throw
        // an error.
        ZygoteHooks.startZygoteNoThreadCreation();

        // Zygote goes into its own process group.
        try {
            Os.setpgid(0, 0);
        } catch (ErrnoException ex) {
            throw new RuntimeException("Failed to setpgid(0,0)", ex);
        }

        final Runnable caller;
        try {
            // Report Zygote start time to tron unless it is a runtime restart
            //...
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;
                } else if ("--enable-lazy-preload".equals(argv[i])) {
                    enableLazyPreload = true;
                } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                    abiList = argv[i].substring(ABI_LIST_ARG.length());
                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                    socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                } else {
                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                }
            }

            if (abiList == null) {
                throw new RuntimeException("No ABI list supplied.");
            }
            //注册一个Socket
            zygoteServer.registerServerSocketFromEnv(socketName);
            // In some configurations, we avoid preloading resources and classes eagerly.
            // In such cases, we will preload things prior to our first fork.
            //判断是否需要预加载
            if (!enableLazyPreload) {
                bootTimingsTraceLog.traceBegin("ZygotePreload");
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                    SystemClock.uptimeMillis());
                //预加载各种资源类
                preload(bootTimingsTraceLog);
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                    SystemClock.uptimeMillis());
                bootTimingsTraceLog.traceEnd(); // ZygotePreload
            } else {
                Zygote.resetNicePriority();
            }
            //...
            if (startSystemServer) {
                //启动SystemServer
                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);

                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                // child (system_server) process.
                if (r != null) {
                    r.run();
                    return;
                }
            }

            caller = zygoteServer.runSelectLoop(abiList);
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            throw ex;
        } finally {
            zygoteServer.closeServerSocket();
        }
        ...
    }

从上面看出,Zygote的主函数其实不复杂,主要完成了以下工作

  • 注册一个Socket
    当有新程序需要时,系统会通过这个socket在第一时间通知ZygoteServer
  • 预加载各类资源
    通过preload函数,加载虚拟机运行时需要的各类资源

2.4 启动SystemServer

        当启动zygote时,启动参数里面带有--start-system-server时,便会调用forkSystemServer来创建SystemServer,看下这个函数的实现:

    private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
        //...
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;
        int pid;
        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            boolean profileSystemServer = SystemProperties.getBoolean(
                    "dalvik.vm.profilesystemserver", false);
            if (profileSystemServer) {
                parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
            }

            //通过这个函数去fork一个新的进程
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.runtimeFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

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

        return null;
    }

上述代码通过调用Zygote.forkSystemServer去创建了一个新进程(具体的fork流程后续再出文章分析),并返回pid,而当pid=0时,将去执行handleSystemServerProcess,继续看这个函数的实现

    private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
        // set umask to 0077 so new files and directories will default to owner-only permissions.
        //...
        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
        if (systemServerClasspath != null) {
            //...
        } else {
            ClassLoader cl = null;
            if (systemServerClasspath != null) {
                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);

                Thread.currentThread().setContextClassLoader(cl);
            }

            /*
             * Pass the remaining arguments to SystemServer.
             */
            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }

        /* should never reach here */
    }

这里实际上是去调用ZygoteInit.zygoteInit

    public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
        if (RuntimeInit.DEBUG) {
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();
        //初始化通用部分
        RuntimeInit.commonInit();
        //初始化native函数
        ZygoteInit.nativeZygoteInit();
        //初始化Application
        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }

在这里有三个初始化函数:

1,commonInit初始化通用部分

2,nativeZygoteInit初始化native部分的服务,内部去调用startThreadPool开启了Binder线程池,保证其他进程能正确访问到zygote

3,applicationInit初始化java服务部分,函数内部根据前面传入的参数,找到SystemServer的main方法,并调用

通过上述步骤,Zygote成功打开了虚拟机,最后去调用SystemServer的main方法。

猜你喜欢

转载自blog.csdn.net/allen_xu_2012_new/article/details/131052014