1、init进程

作为Android开发者和Android使用者,相信每个人都接触过多种Android设备,不管是哪种品牌、哪种类型的Android设置,在使用之前都要完成开机操作,对于普通用户来说开机只是一个操作过程,但对于开发者有没有想过Android是如何开机的?是如何从断电状态启动到可操作交互的?开发者都听过init进程、孵化器进程已经开发中使用的各种服务,那么它们又是如何启动如何工作的呢?带着这些问题进入本篇文章的主题Androdi系统的启动过程;

  • Android系统的启动过程总结
  1. 启动电源:按下电源后,程序从固定地方开始加载引导程序到RAM中
  2. 引导程序BootLoader:Android系统开始执行引导程序,并同时拉起并运行系统的OS
  3. Linux内核启动:当内核启动完成后,首先寻找init.rc配置文件并启动init进程
  4. init进程启动:在init进程中完成属性服务的初始、Zygote进程的启动

由上面的程序启动过程知道,程序在执行完引导程序并启动内核后,首先会查找init文件,在init文件中首先执行main()方法

  • init.main()
......property_init();//1......sigchld_handler_init();//2......start_property_service();......LoadBootScripts(am, sm);static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {    Parser parser = CreateParser(action_manager, service_list);    parser.ParseConfig("/init.rc"); //3}

在main()函数中主要执行一下操作:

  1. 初始化和启动属性服务
  2. 设置进程信号处理
  3. 解析init.rc配置文件
1.1、属性服务初始化与启动
  • 属性服务的初始化
  1. 创建非阻塞的Socket
  2. 调用listen函数对对属性进行监听
  3. 当有数据更新时,init进程会调用handle_property_set_fd函数进行处理
  • 处理客户端请求
  1. 服务属性接收到客户端请求时调用handle_property_set_fd()处理数据
  2. 根据属性分类处理:普通属性、控制属性
1.2、设置进程信号处理
  • 僵尸进程:父进程通过Fork创建子进程,当子进程终止之后,如果父进程不知道此时子进程已结束,此时系统中会仍然保存着进程的信息,那么子进程就会成为僵尸进程
  1. 僵尸进程危害:系统资源有限,僵尸进程会占用系统资源,当资源耗尽时系统将无法创建新的进程

由僵尸进程的定义知道,出现僵尸进程的原因就是父进程与子进程之间通信中断,signal_handler_init函数就是在父进程中监听子进程的状态,在子进程暂停或终止时会发送SIGCHLD信号,signal_handler_init会接收和处理信号,当接收到子进程终止时及时的释放资源

1.3、解析init配置文件

配置文件的解析和处理也是init进程中最主要的部分,安卓中将系统的配置文件保存在init.rc文件中,而Android 8.0之后对init.rc文件浸信会拆分,将每个服务以启动脚本的形式单独存在,然后在init.rc中引入所需要的服务脚本,在启动的时候就可以实现所有服务的启动,这里以接下来要分析的Zygote的启动脚本为例,看看系统是如何定义和处理脚本的

  • 启动脚本——init.zygote64.rc
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server    class main    priority -20    user root    group root readproc reserved_disk    socket zygote stream 660 root system    onrestart write /sys/android_power/request_state wake    onrestart write /sys/power/state on    onrestart restart audioserver    onrestart restart cameraserver    onrestart restart media    onrestart restart netd    onrestart restart wificond    writepid /dev/cpuset/foreground/tasks

启动脚本中参数介绍:

  1. zygote:创建的进程名称
  2. /system/bin/app_process64 :执行的文件路径
  3. class main:表示Zygote的classname为main,后面会根据main查找Zygote服务
  4. onrestart:当进程启动时需要重启的服务

上面启动脚本文件的名称为nit.zygote64.rc,脚本文件名称表示只支持64系统,不过有的启动过脚本会同时支持32为和64为系统,如init.zygote64_32.rc

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote    class main      ......    writepid /dev/cpuset/foreground/tasksservice zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload    class main      .......    writepid /dev/cpuset/foreground/tasks

init.zygote64_32.rc脚本文件中有有两个Zygote服务,一个主模式支持64位的名为zygote进程,另一个辅模式支持32为名为zygote_secondary进程,系统会根据设备的属性决定启动的服务;

  • 解析启动脚本

init进程中会使用ServerParse对Service的启动脚本进行解析,最终会针对启动脚本中的每个服务创建对应的实例,然后将所有的对象实例缓存在Service裢表中,在启动服务时就会从此列表中查找对应的服务对象;

2、Zygote进程启动

在init.rc文件中引入Zygote的启动脚本,所以在解析init.rc配置文件的服务时,就会将Zygote启动脚本中的服务解析保存在Service的裢表中

import /init.${ro.zygote}.rc
  • init启动Zygote进程
on nonencrypted    class_start main    class_start late_start

在解析服务后,会继续init.rc配置文件中的程序,程序执行class_start main,由前面的服务脚本可知classnam为main代表的时Zygote服务,所以此处代表启动Zygote进程,首先会遍历前面保存解析Service的链表,查找classname为main()的服务,然后执行Service中的start()方法;

Result<Success> Service::Start() {pid_t pid = -1;    if (namespace_flags_) {        pid = clone(nullptr, nullptr, namespace_flags_ | SIGCHLD, nullptr);    } else {        pid = fork(); //1、    }    if (pid == 0) { //2、    if (!ExpandArgsAndExecv(args_)) {            PLOG(ERROR) << "cannot execve('" << args_[0] << "')";        }    }}static bool ExpandArgsAndExecv(const std::vector<std::string>& args) {    return execv(c_strings[0], c_strings.data()) == 0; //3、}

在statr()方法中,首先判断进程是否已经运行,对未运行的进程通过fork()创建子进程,创建成功后调用ExpandArgsAndExecv()方法,在ExpandArgsAndExecv()中调用执行execv()后Service进程就被启动并进入Service的main()方法,Zygote进程对应的程序路径为app_main.cpp,在app_main.cpp的main()方法中调用runtime.start()启动进程

int main(int argc, char* const argv[]){        if (strcmp(arg, "--zygote") == 0) { //1            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;       }    }}if (zygote) {       runtime.start("com.android.internal.os.ZygoteInit", args, zygote);   } 

在app_main文件的main()方法中,首先根据进程的名称判断当前是否为Zyote进程,并赋值zygote为true,然后调用runtime.start()启动进程,注意这里的参数传入的是ZygoteInit类的全路径,这里先猜测下最后是根据全路径反射执行ZygoteInit方法,接着看runtime,这里的runtime指的是AndroidRuntime

  • AndroidRuntime.start()
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) != 0) { //1        return;    }    onVmCreated(env);    if (startReg(env) < 0) { // 2        return;    }char* slashClassName = toSlashClassName(className != NULL ? className : "");//3jclass startClass = env->FindClass(slashClassName);// 4jmethodID startMeth = env->GetStaticMethodID(startClass, "main",            "([Ljava/lang/String;)V"); // 5   if (startMeth == NULL) {            ALOGE("JavaVM unable to find main() in '%s'\n", className);   } else {         env->CallStaticVoidMethod(startClass, startMeth, strArray); //6         if (env->ExceptionCheck())            threadExitUncaughtException(env);     }}

在AndroidRuntime的start()方法中,执行了Zygote进程的主要逻辑:

  1. 启动Java虚拟机
  2. 为Java虚拟机注册JNI方法
  3. 通过JNI调用Java层ZygoteInit类中的方法完成进程的启动,此时程序由native进入Java层
  • ZygoteInit
public static void main(String argv[]) {   ZygoteServer zygoteServer = new ZygoteServer();//1   zygoteServer.registerServerSocketFromEnv(socketName);   preload(bootTimingsTraceLog);//2    if (startSystemServer) {     Runnable r = forkSystemServer(abiList, socketName, zygoteServer);//3     if (r != null) {                    r.run();                    return;               }            }   caller = zygoteServer.runSelectLoop(abiList); //4}

程序进入Java层执行ZygoteInit.main()方法,在main()中主要执行:

  1. 首先创建并注册Service端的Socket
  2. 预加载类和资源
  3. 调用forkSystemServer()启动SystemServer进程
  4. 执行zygoteServer.runSelectLoop()循环等待AMS请求创建新的应用进程

关于ZygoteServer的注册和循环等待AMS创建进程的部分之后在AMS启动中介绍,这里先来看看startSystemServer()启动SystemServer进程部分;

4、SystemServer启动过程

SystemServer进程主要用于创建系统服务,如:AMS、WMS、PMS等,由上面知道系统会调用startSystemServer()

private static Runnable forkSystemServer(String abiList, String socketName,       ZygoteServer zygoteServer) {      String args[] = { //1            "--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",        };           parsedArgs = new ZygoteConnection.Arguments(args);  //2        pid = Zygote.forkSystemServer(  //3                    parsedArgs.uid, parsedArgs.gid,                    parsedArgs.gids,                    parsedArgs.runtimeFlags,                    null,                    parsedArgs.permittedCapabilities,                    parsedArgs.effectiveCapabilities); }      if (pid == 0) {             return handleSystemServerProcess(parsedArgs);//4        }

在forkSystemServer()方法中首先将启动参数封装在数组中,然后使用数组创建ZygoteConnection.Arguments对象,最后调用Zygote.forkSystemServer方法fok SystemServer进程,fork进程成功后调用handleSystemServerProcess()处理进程中的工作;

private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {            ClassLoader cl = null;            if (systemServerClasspath != null) {               cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);               Thread.currentThread().setContextClassLoader(cl);            }            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);    }

在handleSystemServerProcess()中首先创建PathClassLoader对象,然后调用ZygoteInit.zygoteInit()方法

  • ZygoteInit.zygoteInit
 public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {        ZygoteInit.nativeZygoteInit(); //1、        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);//2、}

在zygoteInit()中调用nativeZygoteInit()方法,从名字上看出调用的是native方法,在内部通过JNI方法完成Binder线程池的创建,在方法的最后调用RuntimeInit.applicationInit()方法传入ClassLoader,applicationInit()方法相对比较特殊,下面一起看下源码

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,            ClassLoader classLoader) {        final Arguments args = new Arguments(argv);        return findStaticMain(args.startClass, args.startArgs, classLoader);//1    } protected static Runnable findStaticMain(String className, String[] argv,            ClassLoader classLoader) {        Class<?> cl;        try {            cl = Class.forName(className, true, classLoader);//2        } catch (ClassNotFoundException ex) {            throw new RuntimeException(                    "Missing class when invoking static main " + className,                    ex);        }        Method m;        try {            m = cl.getMethod("main", new Class[] { String[].class });//3        } catch (NoSuchMethodException ex) {            throw new RuntimeException(                    "Missing static main on " + className, ex);        } catch (SecurityException ex) {            throw new RuntimeException(                    "Problem getting static main on " + className, ex);        }        int modifiers = m.getModifiers();        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {           throw new RuntimeException(                    "Main method is not public and static on " + className);        }        return new MethodAndArgsCaller(m, argv); //4    }

applicationInit()中调用了findStaticMain()方法,findStaticMain()并没有直接调用SystemServer.main()方法,而是通过反射获取SystemServer的Class,然后获取main()方法,并将main方法和参数封装在MethodAndArgsCaller中,这一点Android P中做了修改,之前的版本中将反射main方法封装在异常中抛出,然后捕捉异常执行,Android P返回了MethodAndArgsCaller对象,MethodAndArgsCaller继承实现Runnable,其实在前面ZygoteInit类中,有一段代码如下

if (startSystemServer) {                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);                if (r != null) {                    r.run();                    return;                }            }

整个SystemServer继承的启动是从调用forkSystemServer()开始的,forkSystemServer返回了Runnable对象,这里的Runnable对象就是上面创建的MethodAndArgsCaller对象,然后调用run()方法执行MethodAndArgsCaller对象;

static class MethodAndArgsCaller implements Runnable {        private final Method mMethod;        private final String[] mArgs;        public MethodAndArgsCaller(Method method, String[] args) {            mMethod = method;            mArgs = args;        }        public void run() {            try {                mMethod.invoke(null, new Object[] { mArgs });            } catch (IllegalAccessException ex) {        }    }

在MethodAndArgsCaller中保存了反射获取的Method,这里的Method就是SystemServer.main()方法,在run方法中调用method.invoke()执行main方法,反射执行之后程序进入SystemServer.main(),main中创建SystemServer对象,并执行run()方法;

public static void main(String[] args) {        new SystemServer().run();    }
  • SystemServer.run()
mSystemServiceManager = new SystemServiceManager(mSystemContext); //1// Start services.        try {            startBootstrapServices();//2            startCoreServices();//3            startOtherServices();//4            SystemServerInitThreadPool.shutdown();        } catch (Throwable ex) {            throw ex;        } 

main方法中直接调用SystemServer.run()方法,在run()方法中,首先创建系统的SystemServiceManager对象,然后依次调用方法启动引导服务、启动核心服务、启动其他服务

  • 启动服务过程
mSystemServiceManager.startService(PowerManagerService.class);  public SystemService startService(String className) {        final Class<SystemService> serviceClass;        try {            serviceClass = (Class<SystemService>)Class.forName(className);        } catch (ClassNotFoundException ex) {        }        return startService(serviceClass);    }

系统调用SystemServerManager.startService()传入对应的服务,在startService()中根据传入的类名加载类文件,然后执行startService(serviceClass)方法,startService中使用加载的Class获取构造函数并创建对象,然后调用startService(service);

Constructor<T> constructor = serviceClass.getConstructor(Context.class);service = constructor.newInstance(mContext);public void startService(@NonNull final SystemService service) {        mServices.add(service); //1        try {            service.onStart();//2        } catch (RuntimeException ex) {    }

在startService()中,先将service注册到mServices中,然后调用service.onStart()方法启动服务;

到此Android系统的启动过程及Zygote的启动过程就介绍完毕了!

更多相关文章

  1. Android 进程和线程模型
  2. 一个简单的Android进程管理器(初稿)
  3. Android进程管理简单介绍
  4. Android中的gen文件为空或者不存在的处理方法
  5. Android进程管理机制及优化
  6. Android进程分类与管理
  7. Android——进程与线程
  8. Android内存管理的原理--进程管理
  9. [Android] Android进程和线程模型

随机推荐

  1. Android(安卓)DrawerLayout demo(抽屉菜
  2. Android(安卓)开源组件PagerBottomTabStr
  3. Android(安卓)ListView中onItemClickList
  4. Android(安卓)ExpandableListView折叠
  5. Android(安卓)自定义滚动选择日期
  6. Android(安卓)单选按钮RadioButton的使用
  7. 如何在Android5.1系统上实现RecyclerView
  8. 八款开源Android(安卓)游戏引擎介绍
  9. 毕业设计心得与整理-APP-主题切换
  10. Activity作为dialog展示,如何添加自定义