• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > Android5 Zygote 与 SystemServer 启动流程分析

Android5 Zygote 与 SystemServer 启动流程分析

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了android5,升级android5吗,精通android5,android5系统下载,android5下载等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Android5 Zygote 与 SystemServer 启动流程分析


Android5 Zygote 与 SystemServer 启动流程分析

前言

Android5.0.1 的启动流程与之前的版本相比变化并不大,OK,变化虽然还是有:SystemServer 启动过程的 init1(), init2()没有了,但主干流程依然不变:Linux 内核加载完毕之后,首先启动 init 进程,然后解析 init.rc,并根据其内容由 init 进程装载 Android 文件系统、创建系统目录、初始化属性系统、启动一些守护进程,其中最重要的守护进程就是 Zygote 进程。Zygote 进程初始化时会创建 Dalvik 虚拟机、预装载系统的资源和 Java 类。所有从 Zygote 进程 fork 出来的用户进程都将继承和共享这些预加载的资源。init 进程是 Android 的第一个进程,而 Zygote 进程则是所有用户进程的根进程。SystemServer 是 Zygote 进程 fork 出的第一个进程,也是整个 Android 系统的核心进程。

zygote 进程

解析 zygote.rc

在文件中 /system/core/rootdir/init.rc 中包含了 zygote.rc:

import /init.${ro.zygote}.rc

${ro.zygote}是平台相关的参数,实际可对应到 init.zygote32.rc, init.zygote64.rc, init.zygote64_32.rc, init.zygote32_64.rc,前两个只会启动单一app_process(64) 进程,而后两个则会启动两个app_process进程:第二个app_process进程称为 secondary,在后面的代码中可以看到相应 secondary socket 的创建过程。为简化起见,在这里就不考虑这种创建两个app_process进程的情形。

以 /system/core/rootdir/init.zygote32.rc 为例:

    service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart media
    onrestart restart netd

第一行创建了名为 zygote 的进程,这个进程是通过 app_process 的 main 启动并以”-Xzygote /system/bin –zygote –start-system-server”作为main的入口参数。

app_process 对应代码为 framework/base/cmds/app_process/app_main.cpp。在这个文件的main函数中:

AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));

    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args);
    }

根据入口参数,我们知道 zygote 为true,args参数中包含了”start-system-server”。

AppRuntime 继承自 AndroidRuntime,因此下一步就执行到 AndroidRuntime 的 start 函数。

void AndroidRuntime::start(const char* className, const Vector& options)
{
    /* start the virtual machine */ // 创建虚拟机
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env) != 0) {
        return;
    }
    onVmCreated(env);

    ...
    //调用className对应类的静态main()函数
    char* slashClassName = toSlashClassName(className);
    jclass startClass = env->FindClass(slashClassName);
    jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
    env->CallStaticVoidMethod(startClass, startMeth, strArray);
    ...
}

start函数主要做两件事:创建虚拟机和调用传入类名对应类的 main 函数。因此下一步就执行到 com.android.internal.os.ZygoteInit 的 main 函数。

    public static void main(String argv[]) {
        try {
            boolean startSystemServer = false;
            String socketName = "zygote";
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;
                }
                ...
            }

            registerZygoteSocket(socketName);
            ...
            preload();
            ...

            if (startSystemServer) {
                startSystemServer(abiList, socketName);
            }

            Log.i(TAG, "Accepting command socket connections");
            runSelectLoop(abiList);

            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }

它主要做了三件事情:
1. 调用 registerZygoteSocket 函数创建了一个 socket 接口,用来和 ActivityManagerService 通讯;
2. 调用 startSystemServer 函数来启动 SystemServer;
3. 调用 runSelectLoop 函数进入一个无限循环在前面创建的 socket 接口上等待 ActivityManagerService 请求创建新的应用程序进程。

这里要留意 catch (MethodAndArgsCaller caller) 这一行,android 在这里通过抛出一个异常来处理正常的业务逻辑。

    socket zygote stream 660 root system

系统启动脚本文件 init.rc 是由 init 进程来解释执行的,而 init 进程的源代码位于 system/core/init 目录中,在 init.c 文件中,是由 service_start 函数来解释 init.zygote32.rc 文件中的 service 命令的:

    void service_start(struct service *svc, const char *dynamic_args)
    {
        ...
        pid = fork();

        if (pid == 0) {
            struct socketinfo *si;
            ...

            for (si = svc->sockets; si; si = si->next) {
                int socket_type = (
                        !strcmp(si->type, "stream") ? SOCK_STREAM :
                            (!strcmp(si->type, "dgram") ? SOCK_DGRAM : SOCK_SEQPACKET));
                int s = create_socket(si->name, socket_type,
                                      si->perm, si->uid, si->gid, si->socketcon ?: scon);
                if (s >= 0) {
                    publish_socket(si->name, s);
                }
            }
            ...
        }
        ...
    }

每一个 service 命令都会促使 init 进程调用 fork 函数来创建一个新的进程,在新的进程里面,会分析里面的 socket 选项,对于每一个 socket 选项,都会通过 create_socket 函数来在 /dev/socket 目录下创建一个文件,在 zygote 进程中 socket 选项为“socket zygote stream 660 root system”,因此这个文件便是 zygote了,然后得到的文件描述符通过 publish_socket 函数写入到环境变量中去:

    static void publish_socket(const char *name, int fd)
    {
        char key[64] = ANDROID_SOCKET_ENV_PREFIX;
        char val[64];

        strlcpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1,
                name,
                sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX));
        snprintf(val, sizeof(val), "%d", fd);
        add_environment(key, val);

        /* make sure we don't close-on-exec */
        fcntl(fd, F_SETFD, 0);
    }

这里传进来的参数name值为”zygote”,而 ANDROID_SOCKET_ENV_PREFIX 在 system/core/include/cutils/sockets.h 定义为:

#define ANDROID_SOCKET_ENV_PREFIX   "ANDROID_SOCKET_"
#define ANDROID_SOCKET_DIR          "/dev/socket"

因此,这里就把上面得到的文件描述符写入到以 “ANDROID_SOCKET_zygote” 为 key 值的环境变量中。又因为上面的 ZygoteInit.registerZygoteSocket 函数与这里创建 socket 文件的 create_socket 函数是运行在同一个进程中,因此,上面的 ZygoteInit.registerZygoteSocket 函数可以直接使用这个文件描述符来创建一个 Java层的LocalServerSocket 对象。如果其它进程也需要打开这个 /dev/socket/zygote 文件来和 zygote 进程进行通信,那就必须要通过文件名来连接这个 LocalServerSocket了。也就是说创建 zygote socket 之后,ActivityManagerService 就能够通过该 socket 与 zygote 进程通信从而 fork 创建

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Android 5.0(包含5.0以下版本) 获取栈顶应用程序包名,android包名
  • Android5.0开发范例大全 读书笔记(五),android5.0范例
  • Android5.0开发范例大全 读书笔记(六),android5.0范例
  • Android5.0开发范例大全 读书笔记(三),android5.0范例
  • Android5.0开发范例大全 读书笔记(四),android5.0范例
  • android 5.0后对于apk 跑32 64 的逻辑
  • Android 5.0 Settings源码简要分析
  • Android5.0新特性-Material Design
  • Android5.0之Toobar的使用
  • ubuntu下安装AndroidStudio

相关文章

  • 2017-05-26Android 环境搭建 以及 第一个android 程序的编写,搭建android
  • 2017-07-22详解Android中的SQLite数据库存储
  • 2017-05-26对View的onMeasure()方法的进一步研究,viewonmeasure
  • 2017-05-26Android动画三部曲之一 View Animation &amp; LayoutAnimation
  • 2017-05-26安卓开发 第一篇 关于依赖注入框架dagger2的使用和理解
  • 2017-05-26Solaris IPMP两种配置方法
  • 2017-05-26Android笔记——Android自定义控件,android自定义控件
  • 2017-05-26自定义Toast的显示位置和显示内容,自定义toast
  • 2017-05-26Android基础部分再学习---activity的生命周期
  • 2017-05-26Android手机输入法按键监听-dispatchKeyEvent

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Android登录客户端,验证码的获取,网页数据抓取与解析,HttpWatch基本使用
    • Android中AsyncTask的使用详解
    • Android(Linux)实时监测串口数据,android实时监测
    • Android Studio NDK基础使用
    • 谷歌电子市场5--推荐,谷歌电子市场5--
    • android插件开发-就是你了!启动吧!插件的activity(二)
    • 分析和优化应用电量
    • mmap实现分析
    • Android自定义实现循环滚轮控件WheelView
    • 我的第一篇博客,我试试怎么用,第一篇博客,试试

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有