Zygote 与/dev/socket/zygote
来源:互联网 发布:keil模块化编程认识 编辑:程序博客网 时间:2024/06/05 08:50
1、zygote socket 的创建
apk的启动是ams 通过socket 与zygote 通信,然后由zygote fork出来一个进程,来加载运行apk的。
ams 与zygote 通信的socket 是在系统启动时,由init.zygote*.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
这条init.zygote*.rc 中的配置意思为:
a、service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
去通过app_process 启动 zygote 进程
b、socket zygote stream 660 root system
创建ams 与 zygote 通信的 socket,(/dev/socket)
由配置转化为代码的具体实现是在:
system/core/init/property_service.cpp
void service_start(struct service *svc, const char *dynamic_args){ 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); //此处name为zygote } execve(svc->args[0], (char**) arg_ptrs, (char**) ENV);}
由init.rc 调用到此处那么: create_socket
为创建名为zygote 的socket publish_socket
为将创建的socket 的fd 放入 环境变量:ANDROID_SOCKET_zygote 中,以便在zygote进程中,获取此socket的fd
execve 为根据init.rc 里面的命令去创建zygote 进程。
publish_socket 将socket 的fd公布出来的具体实现为:
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);}
add_environment
以拼接的ANDROID_SOCKET_zygote 为key, socket 的fd 为val,添加进入环境变量。
变量 ANDROID_SOCKET_ENV_PREFIX 为
include/cutils/sockets.h:33:#define ANDROID_SOCKET_ENV_PREFIX “ANDROID_SOCKET_”
到此Zygote 的socket 就创建完毕,之后会去创建zygote 进程。
2、zygote 进程的创建,并与socket的关联
创建zygote
init.zygote*.rc 会通过执行app_process 命令去创建 zygote 进程
if (zygote) { runtime.start("com.android.internal.os.ZygoteInit", args, zygote); } else if (className) { runtime.start("com.android.internal.os.RuntimeInit", args, zygote);}
在AndroidRuntime.cpp 中会进行一系列的操作,然后反射调用 ZygoteInit 的main方法:
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) { char* slashClassName = toSlashClassName(className); jclass startClass = env->FindClass(slashClassName); if (startClass == NULL) { ALOGE("JavaVM unable to locate class '%s'\n", slashClassName); } else { jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); if (startMeth == NULL) { ALOGE("JavaVM unable to find main() in '%s'\n", className); } else { env->CallStaticVoidMethod(startClass, startMeth, strArray); } } free(slashClassName); *// 因为其他进程也是由zygote 进程fork 出来的,所有其他进程也包含这段代码,如果其他进程在java 层crash,那么也会走到这里,打印此log,所以常见此log* ALOGD("Shutting down VM\n");}
zygote关联init中创建的socket
系统通过ZygoteInit的main方法进入java 世界,在此方法中,会通过之前配置的环境变量:
ANDROID_SOCKET_zygote
获取init.rc中创建的zygote socket的fd,并开始循环监听等待连接。
public static void main(String argv[]) { String socketName = "zygote"; try { registerZygoteSocket(socketName); if (startSystemServer) { startSystemServer(abiList, socketName); } runSelectLoop(abiList); } catch (MethodAndArgsCaller caller) { caller.run(); //此处是为了,ams 通过socket 与zygote通信,建立进程时,反射调用他的入口类。 }}
registerZygoteSocket
去 获取socket 的fd,并根据fd 创建出对应的LocalServerSocket 对象 startSystemServer
从zygote 中fork出,system_server 进程,并在进程启动后,连接一次 zygote的socket,由此将system_server的输入端输出端,与zygote 进程打通 runSelectLoop
开始去循环监听 socket
registerZygoteSocket
在zygote 中创建socket的服务端
private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_" private static void registerZygoteSocket(String socketName) { int fileDesc; //拼接出ANDROID_SOCKET_zygote 字符串 final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName; //从环境变量中获取 ANDROID_SOCKET_zygote 对应的fd 值 String env = System.getenv(fullSocketName); fileDesc = Integer.parseInt(env); FileDescriptor fd = new FileDescriptor(); fd.setInt$(fileDesc); //根据fd值,创建出socket服务端。 sServerSocket = new LocalServerSocket(fd); } } }
startSystemServer
会从zygote 中fork 出system_server 进程,并在system_server 进程中,通过socket 连接zygote
private static boolean startSystemServer(String abiList, String socketName){ //从zygote 中fork出system_server pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); if (pid == 0) { if (hasSecondZygote(abiList)) { //在system_server进程中首次连接 zygote 的socket //waitForSecondaryZygote 中会去连接名为:zygote 的socket,如果连接不上,表示zygote 那边还没有准备好,等待一秒继续连接,直到连接成功。 waitForSecondaryZygote(socketName); } //加载初始化 sysmte_server进程 handleSystemServerProcess(parsedArgs); }}
runSelectLoop
开始去循环监听 socket,等待system_server 的连接。
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller { ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>(); ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>(); fds.add(sServerSocket.getFileDescriptor()); //将socket 服务端添加进入fds peers.add(null); //开始循环监听 while (true) { StructPollfd[] pollFds = new StructPollfd[fds.size()]; //设置参数,只监听 fd 是否有数据可读 for (int i = 0; i < pollFds.length; ++i) { pollFds[i] = new StructPollfd(); pollFds[i].fd = fds.get(i); pollFds[i].events = (short) POLLIN; } try { //监听 socket 是否数据可读,如果没有那么 会在此处等待 Os.poll(pollFds, -1); } catch (ErrnoException ex) { throw new RuntimeException("poll failed", ex); } for (int i = pollFds.length - 1; i >= 0; --i) { if (i == 0) { //此处对应之前,system_server 启动时,会首次与Zygote 连接, 此处将system_server 端的连接对象ZygoteConnection存储下来,以便之后读取ams 写入socket的参数 ZygoteConnection newPeer = acceptCommandPeer(abiList); peers.add(newPeer); //将连接对象添加进入 peer中,peer 数据对应为 0 ---> zygote 1---->system_server fds.add(newPeer.getFileDesciptor()); } else { //当有数据传入时,会调用system_server的 ZygoteConnectiond对象的,在此runOnce方法中,会获取ams写入socket的参数, boolean done = peers.get(i).runOnce(); if (done) { peers.remove(i); fds.remove(i); } } } } }}
到此:
zygote 开始循环监听 /dev/socket/zygote
system_server 与zygote 达成首次通信,
zygote 保存下 system_server 的连接对象 ZygoteConnection
都已完成,
之后如果ams 再去连接 /dev/socket/zygote 那么会调用runOnce 去fork 新进程,启动apk。
- Zygote 与/dev/socket/zygote
- System_server 与/dev/socket/zygote
- zygote
- Zygote
- ZYgote
- Zygote
- Zygote
- System_Server与Zygote共存亡
- init进程与zygote进程
- Zygote Service
- Zygote 分析
- zygote-->system_server
- Zygote分析
- Zygote简析
- [5] Zygote
- Zygote Service
- Zygote Service
- Zygote详解
- 浅看Android与IOS
- cmake交叉编译
- OpenGL蓝宝书源码学习(十)第五章——纹理的应用、Mip贴图、各项异性过滤和纹理压缩基础
- Java34
- 一步一步理解Basic Paxos算法
- Zygote 与/dev/socket/zygote
- 简单Android应用开发全流程
- 关于面向对象的一次争论
- ubuntu更新源出现配置错误解决方案
- onvif基础框架搭建与简单开发
- Hive学习笔记 --- RCFile介绍
- 哈希表与哈希函数简介
- Java35
- MySQL定时备份