一、关于Android系统重要的进程

(1)、init进程:init进程是Linux内核启动完成之后,启动的第一个用户进程,Android系统就是在这个进程的基础上启动起来的,进程pid为1。init进程通过解析init.rc来陆续启动其他关键的系统服务进程---其中最重要的是:ServiceManagerZygoteSystemServer

(2)、ServiceManager:主要负责添加服务,获取服务,查找服务以及当某个服务意外终止时,对该服务的资源进行回收。
(3)、Zygote进程:Zygote是一个孵化器进程,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程fork出来的。在Zygote中进行添加虚拟机参数,并将其启动起来,然后注册JNI函数。在Zygote中进行预加载以及初始化核心类库。最后将SystemServer启动起来。
(4)、SystemServer:启动系统各项服务。

二、init.rc脚本语法规则

service <name> <pathname> [ <argument> ]*   //service的名字,启动路径,以及参数<option>      <option>...

<name>:
表示此service的名称
<pathname>:
此service所在的路径。因为是可执行文件,所以一定有存储路径。
<argument>:
启动service所带的参数。
<option>:
对此service的约束选项。

三、ServiceManager,Zygote,SystemServer的启动简析

3.1 ServiceManager

ServiceManager是Binder机制中的“DNS服务器”,负责域名(某Binder服务在ServiceManager注册时提供的名称)IP地址(由底层Binder驱动分配的值)的解析。
       ServiceManager是在servicemanager.rc(Android8.0)里面描述,并由init进程启动。

/*android-8.0.0_r1\frameworks\native\cmds\servicemanager\servicemanager.rc*/
service servicemanager /system/bin/servicemanagerclass core animationuser systemgroup system readproccriticalonrestart restart healthdonrestart restart zygoteonrestart restart audioserveronrestart restart mediaonrestart restart surfaceflingeronrestart restart inputflingeronrestart restart drmonrestart restart cameraserverwritepid /dev/cpuset/system-background/tasks

可以看到,Servicemanager是一个Linux程序。它在设备中的存储路径是:/system/bin/servicemanager,源码路径则是:
android-8.0.0_r1\frameworks\native\cmds\servicemanager\servicemanager.c

ServiceManager所属的classcore,其他同类的系统进程包括ueventd,console(/system/bin/sh),adbd等。根据core组的特性,这些进程会同时被启动或停止。另外,critical选项说明它是系统的关键进程---意味着如果进程不幸在4分钟内异常退出超过4次,则设备将重启并进入还原模式。当ServiceManager每次重启是,其他关键进程如zygote,media,surfaceflinger等也会被restart。

3.2 Zygote

在Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的,因为Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程fork出来的。Zygote进程也不例外,它是在系统启动的过程,由init进程创建的,在系统启动脚本android-8.0.0_r1\system\core\rootdir\init.*.rc文件中,我们可以看到启动Zygote进程的脚本命令:

/*android-8.0.0_r1\system\core\rootdir\init.*.rc*/例如:init.zygote32.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-serverclass mainpriority -20user rootgroup root readprocsocket zygote stream 660 root systemonrestart write /sys/android_power/request_state wakeonrestart write /sys/power/state ononrestart restart audioserveronrestart restart cameraserveronrestart restart mediaonrestart restart netdonrestart restart wificondwritepid /dev/cpuset/foreground/tasks

从上面这段脚本描述可以看出:
ServiceName:zygote
Path:/system/bin/app_process
Arguments:-Xzygote /system/bin --zygote --start-system-server

Zygote所属classmain,而不是core。和其同class的系统进程有netd,debuggerd,rild等。从zygote的path可以看出,它所在的应用程序名叫"app_process"。通过指定--zygote参数,app_process可以识别出用户是否需要启动zygote。
"app_process"程序源码路径在:android-8.0.0_r1\frameworks\base\cmds\app_process\app_main.cpp中。

app_process_path.png

android-8.0.0_r1\frameworks\base\cmds\app_process\Android.mk主要内容:

LOCAL_SRC_FILES:= \app_main.cppLOCAL_LDFLAGS := -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--export-dynamicLOCAL_SHARED_LIBRARIES := \libdl \libcutils \libutils \liblog \libbinder \libnativeloader \libandroid_runtime \$(app_process_common_shared_libs) \LOCAL_WHOLE_STATIC_LIBRARIES := libsigchainLOCAL_MODULE:= app_process

"app_process"的源码路径在:
android-8.0.0_r1\frameworks\base\cmds\app_process\app_main.cpp
其主要函数:

int main(int argc, char* const argv[])
{...AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));// After the parent dir, we expect one or more the following internal// arguments ://// --zygote : Start in zygote mode// --start-system-server : Start the system server.// --application : Start in application (stand alone, non zygote) mode.// --nice-name : The nice name for this process.// Parse runtime arguments.  Stop at first unrecognized option.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++];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;}}Vector<String8> args;if (!className.isEmpty()) {// We're not in zygote mode, the only argument we need to pass// to RuntimeInit is the application argument.//// The Remainder of args get passed to startup class main(). Make// copies of them before we overwrite them with the process name.args.add(application ? String8("application") : String8("tool"));runtime.setClassNameAndArgs(className, argc - i, argv + i);} else {// We're in zygote mode.maybeCreateDalvikCache();if (startSystemServer) {args.add(String8("start-system-server"));}char prop[PROP_VALUE_MAX];if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",ABI_LIST_PROPERTY);return 11;}String8 abiFlag("--abi-list=");abiFlag.append(prop);args.add(abiFlag);// In zygote mode, pass all remaining arguments to the zygote// main() method.for (; i < argc; ++i) {args.add(String8(argv[i]));}}if (!niceName.isEmpty()) {runtime.setArgv0(niceName.string());set_process_name(niceName.string());}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.");return 10;}
}

因为,在此init.rc指定了--zygote选项,因而app_process接下来将启动"ZygoteInit"并传入"start-system-server"。
AppRuntime 继承自AndroidRuntime,所以,runtime.start()函数对应源码:
android-8.0.0_r1\frameworks\base\core\jni\AndroidRuntime.cpp

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
.../* start the virtual machine */JniInvocation jni_invocation;jni_invocation.Init(NULL);JNIEnv* env;if (startVm(&mJavaVM, &env, zygote) != 0) {//启动虚拟机return;}onVmCreated(env);//虚拟机启动后的回调/** Register android functions.*/if (startReg(env) < 0) {ALOGE("Unable to register all android natives\n");return;}...}

除了与装载各种系统类(具体实现在ZygoteInit#preload()这个方法里)外,ZygoteInit的另一个重要工作就是启动SystemServer---这是大部分Android系统服务(由Java语言编写)的所在地。

3.3 SystemServer(Android的系统服务)

SystemServer是Android进入Laucher前的最后准备。
       一旦在init.rc中为zygote指定了启动参数--start-system-server,那么ZygoteInit就会调用startSystemServer来启动SystemServer。

    private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)throws Zygote.MethodAndArgsCaller, RuntimeException {.../* Hardcoded command line to start the system server */String args[] = {"--setuid=1000","--setgid=1000","--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010","--capabilities=" + capabilities + "," + capabilities,"--nice-name=system_server","--runtime-args","com.android.server.SystemServer",};ZygoteConnection.Arguments parsedArgs = null;int pid;try {parsedArgs = new ZygoteConnection.Arguments(args);...pid = Zygote.forkSystemServer(parsedArgs.uid, parsedArgs.gid,parsedArgs.gids,parsedArgs.debugFlags,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();handleSystemServerProcess(parsedArgs);}return true;}

根据fork的特性,子进程和父进程将获得同样的代码环境。当变量pid值为0时,说明是子进程,否则是父进程;如果是前者的话,则进一步调用handleSystemServerProcess来完成剩下的工作,也是最核心的部分---启动各种系统服务。并在一切准备就绪后进入Launcher主界面。

【Android源码分析】Android系统关键服务启动简析相关推荐

  1. 【Android 源码学习】系统架构和启动流程

    Android 源码学习 系统架构和启动流程 望舒课堂 学习记录整理.以及以下参考文章的整理汇总.便于我个人的学习记录. 感谢IngresGe,Gityuan的精彩文章.为我们这些初探android系 ...

  2. adb android源码分析,Android Adb 源码解析(base on Android 9.0)

    Adb 框架 Adb架构 Android Adb 一共分为三个部分:adb.adb server.adbd,源码路径:system⁩/⁨core⁩/⁨adb. adb和adb server 是运行在P ...

  3. Android 源码分析(三) Service 启动分析

    //android-8.0.0_r1\frameworks\base\core\java\android\content\Context.java/** * startService是Context的 ...

  4. adb android源码分析,Android源码分析(十六)----adb shell 命令进行OTA升级

    一: 进入shell命令界面 adb shell 二:创建目录/cache/recovery mkdir /cache/recovery 如果系统中已有此目录,则会提示已存在. 三: 修改文件夹权限 ...

  5. Android源码分析(三)-----系统框架设计思想

    一 : 术在内而道在外 Android系统的精髓在源码之外,而不在源码之内,代码只是一种实现人类思想的工具,仅此而已...... 近来发现很多关于Android文章都是以源码的方向入手分析Androi ...

  6. (连载)Android系统源码分析--Android系统启动流程之Linux内核

    > **这是一个连载的博文系列,我将持续为大家提供尽可能透彻的Android源码分析 [github连载地址](https://github.com/foxleezh/AOSP/issues/3 ...

  7. Android 源码分析

    查看源码版本号: build\core\version_defaults.mk //搜索该文件中的 PLATFORM_VERSION值 frameworks 目录 (核心框架--java及C++语言) ...

  8. Android源码分析 - Framework层的Binder(客户端篇)

    开篇 本篇以aosp分支android-11.0.0_r25作为基础解析 我们在之前的文章中,从驱动层面分析了Binder是怎样工作的,但Binder驱动只涉及传输部分,待传输对象是怎么产生的呢,这就 ...

  9. Android源码分析-全面理解Context

    前言 Context在android中的作用不言而喻,当我们访问当前应用的资源,启动一个新的activity的时候都需要提供Context,而这个Context到底是什么呢,这个问题好像很好回答又好像 ...

最新文章

  1. javascript dom节点x
  2. 1050 String Subtraction
  3. oracle ocp笔记(1)
  4. 秦汉考场科目三路线图_我在青竹湖考场考科三的一些分享
  5. sh(Spring+Spring mvc+hibernate)——IDeptDao.java
  6. valgrind检测libevent内存泄露
  7. xib中UIScrollView固定底部内容
  8. java阻塞锁_java – 阻止锁与非阻塞锁
  9. IDC带宽测试几款软件(Multiping pingPlotter TracertGUI )
  10. 解决ajax无法给js全局变量赋值的问题
  11. MATLAB 动图绘制、保存
  12. 基于Windows NBL配置WebInterface
  13. 手机上如何让页面强制横屏
  14. [SeLinux]audit2allow安装与使用
  15. php实现室内地图导航,室内三维地图引擎功能
  16. 乒乓球侧旋球MATLAB,【动图】看动图让你了解乒乓球的侧旋转
  17. css实现闪烁的灯,纯CSS实现的闪烁霓虹灯文本动画特效
  18. 光伏板怎么申请ASTM E108阻燃测试?
  19. 注销系统的logout命令
  20. bat 格式化年月日时分秒

热门文章

  1. 腾讯云存储上传头像、文件功能(超详细保姆级)
  2. Klocwork — 符合功能安全要求的自动化静态测试工具
  3. 移动支付发展至今有什么优势?
  4. Golang 基础之基础语法梳理 (三)
  5. [EOS源码分析]2.EOS账号钱包密钥等基本概念及操作实践
  6. J2EE进阶(二十四)JBoss Web和 Tomcat的区别
  7. 程序与生活的一点反思(常看而反思)
  8. 毕业多年的程序员重拾英语考雅思
  9. HttpClient设置超时时间无效
  10. (29) JavaWeb中使用filter过滤器拦截请求、权限检查,过滤响应。