热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android学习zygote(上)

Zygote意思是受精卵,它在Java世界中起到了很重要的作用,Android是基于Linux内核的,SDK是基于Java世界的ÿ

Zygote意思是受精卵,它在Java世界中起到了很重要的作用,Android是基于Linux内核的,SDK是基于Java世界的,native语言是基于C和C++,起初一定是先存在native世界,那么Java世界是如何创建的?这就与zygote和system_server有关。

 

Zygote是一个native应用程序,原名是app_process,是在Android.mk文件中指定的,但是在运行的时候通过Linux下的pctrl系统调用将自己的名字改成了zygote,在0frameworks/base/cmds/app_process目录下,app_main函数中:

if (0 == strcmp("--zygote", arg)) {bool startSystemServer = (i

上面的函数中,调用了AppRuntime中的start方法,AppRuntime继承AndroidRuntime,调用的start也是AndroidRuntime里的方法。

AndroidRuntime.cpp

①//创建虚拟机
if (startVm(&mJavaVM, &env) != 0) goto bail; ②注册JNI函数if (startReg(env) <0) {LOGE("Unable to register all android natives\n");goto bail;
}③ 通过JNI调用ZygoteInit下的main函数 进入Java世界
env->CallStaticVoidMethod(startClass, startMeth, strArray);

1 创建虚拟机

int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)//大部分是设置虚拟机参数
{
//设置JNI check选项的 检查资源是否被正确释放 字符集的要求等 缺点:耗时
property_get("dalvik.vm.checkjni", propBuf, "");//设置虚拟机的heapsize 默认是16MB 太小会导致操作大图片的时候无法分配内存strcpy(heapsizeOptsBuf, "-Xmx");property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m");
}

2 注册JNI函数

/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{ //设置Thread类的线程创建函数是javaCreateThreadEtcandroidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);env->PushLocalFrame(200);// 注册JNI函数 gRegJNI是一个全局数组
/*register_jni_procs函数里调用数组的Proc方法,Proc方法是为了注册JNI函数,数组是gRegJNI包含了所需要注册的JNI函数*/if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) <0) {env->PopLocalFrame(NULL);return -1;}env->PopLocalFrame(NULL);//createJavaThread("fubar", quickTest, (void*) "hello");return 0;
}

 

接下来就进入了Java世界,Java世界的入口---frameworks/base/core/java/com/android/internal/os  ZygoteInit.java

public static void main(String argv[]) {
try{
registerZygoteSocket(); //① 注册zygote用到的socketpreloadClasses(); //②预加载类和资源
preloadResources();if (argv[1].equals("true")) {startSystemServer(); //③启动SystemServer}if (ZYGOTE_FORK_MODE) {runForkMode(); //④
} else {runSelectLoopMode();}
}catch(MethodAndArgsCaller caller){
caller.run(); //⑤
}
}

  • 建立IPC通信服务端registerZygoteSocket

IPC---InterProcess Communication 进程间通信,指的是在不同进程之间传播交换信息,不同进程之间用户空间独立,共享内存区是公用的,常见的IPC通信有:管道、消息队列、 信号量、共享内存、socket、Streams等


private static void registerZygoteSocket() {if (sServerSocket == null) {int fileDesc;try { //从环境变量获取socket的fd(启动时传入)String env = System.getenv(ANDROID_SOCKET_ENV);fileDesc = Integer.parseInt(env);} ......try { //创建服务端socketsServerSocket = new LocalServerSocket(createFileDescriptor(fileDesc));}......}}

  1. 预加载类和资源

private static void preloadClasses() {//预加载的类信息存储在PRELOADED_CLASSES里InputStream is = ZygoteInit.class.getClassLoader().getResourceAsStream(
if (is == null) {Log.e(TAG, "Couldn&#39;t find " + PRELOADED_CLASSES + ".");} else { //准备工作 }
//读取文件的每一行while ((line = br.readLine()) != null) {// Skip comments and blank lines.line = line.trim();if (line.startsWith("#") || line.equals("")) {continue;}//通过Java反射来加载类 line中存储的是预加载的类名Class.forName(line);
}

在/AOSP/frameworks/base/preloaded-classes下是要加载的所有类,数量很多高达1200+行

 Preload_class文件由framework/base/tool/preload工具生成,他要判断每个类加载的时间是否大于1250us,超过这个时间写入到preload_classes文件中,由zygote预加载。由于要加载的类十分多,这也导致了android启动时间很长。

③启动system_server

StartSystemServer会创建Java世界中系统Service所驻留的进程,该进程是framework核心,他如果死了,zygote就会自杀。zygote压力大,分裂了一个子进程为他做一些事情。

private static boolean startSystemServer()throws MethodAndArgsCaller, RuntimeException {
//设置参数String args[] = {"--setuid=1000","--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003","--capabilities=130104352,130104352","--runtime-init","--nice-name=system_server",//进程名"com.android.server.SystemServer",};ZygoteConnection.Arguments parsedArgs = null;int pid;try {parsedArgs = new ZygoteConnection.Arguments(args);int debugFlags = parsedArgs.debugFlags;if ("1".equals(SystemProperties.get("ro.debuggable")))debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;/* zygote分裂了一个子进程 */pid = Zygote.forkSystemServer(parsedArgs.uid, parsedArgs.gid,parsedArgs.gids, debugFlags, null,parsedArgs.permittedCapabilities,parsedArgs.effectiveCapabilities);} catch (IllegalArgumentException ex) {throw new RuntimeException(ex);}if (pid == 0) {//pid=0表明处于子进程中,开始执行system_server的工作handleSystemServerProcess(parsedArgs);}return true;}

④ runSelectLoopMode

当函数分裂了system_server进程后进入到了下一个关键函数runSelectLoopMode,这里将会使用到前面第一步创建的socket

private static void runSelectLoopMode() throws MethodAndArgsCaller {ArrayList fds = new ArrayList();ArrayList peers = new ArrayList();FileDescriptor[] fdArray = new FileDescriptor[4];
//第一步创建的服务端socketfds.add(sServerSocket.getFileDescriptor());peers.add(null);
while (true) {int index=0;try {
//selectReadable内部调用select,使用多路复用IO模型,有客户端连接//或者有数据时//selectReadable就会返回fdArray = fds.toArray(fdArray);index = selectReadable(fdArray);} catch (IOException ex) {throw new RuntimeException("Error in select()", ex);}
//客户端代表的是ZygoteConnection,
else if (index == 0) {ZygoteConnection newPeer = acceptCommandPeer();peers.add(newPeer);fds.add(newPeer.getFileDesciptor());} else {boolean done;
// peers.get(index)返回的是ZygoteConnection,然后调用runOnce函数完成dOne= peers.get(index).runOnce();
}

总结:主要是处理客户连接和客户请求,客户在zygote中用ZygoteConnection 表示,客户的请求由runOnce函数完成。

至此Zygote便睡去了,默默守护在我们周围。当收到子孙后代的请求后,会被随时叫醒。

下一章节,将来学习Zygote的子进程SystemServer


推荐阅读
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • Week04面向对象设计与继承学习总结及作业要求
    本文总结了Week04面向对象设计与继承的重要知识点,包括对象、类、封装性、静态属性、静态方法、重载、继承和多态等。同时,还介绍了私有构造函数在类外部无法被调用、static不能访问非静态属性以及该类实例可以共享类里的static属性等内容。此外,还提到了作业要求,包括讲述一个在网上商城购物或在班级博客进行学习的故事,并使用Markdown的加粗标记和语句块标记标注关键名词和动词。最后,还提到了参考资料中关于UML类图如何绘制的范例。 ... [详细]
  • 本文介绍了Java调用Windows下某些程序的方法,包括调用可执行程序和批处理命令。针对Java不支持直接调用批处理文件的问题,提供了一种将批处理文件转换为可执行文件的解决方案。介绍了使用Quick Batch File Compiler将批处理脚本编译为EXE文件,并通过Java调用可执行文件的方法。详细介绍了编译和反编译的步骤,以及调用方法的示例代码。 ... [详细]
  • 近来有一个需求,是需要在androidjava基础库中插入一些log信息,完成这个工作需要的前置条件有编译好的android源码具体android源码如何编译,这 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • PHP中的单例模式与静态变量的区别及使用方法
    本文介绍了PHP中的单例模式与静态变量的区别及使用方法。在PHP中,静态变量的存活周期仅仅是每次PHP的会话周期,与Java、C++不同。静态变量在PHP中的作用域仅限于当前文件内,在函数或类中可以传递变量。本文还通过示例代码解释了静态变量在函数和类中的使用方法,并说明了静态变量的生命周期与结构体的生命周期相关联。同时,本文还介绍了静态变量在类中的使用方法,并通过示例代码展示了如何在类中使用静态变量。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • Annotation的大材小用
    为什么80%的码农都做不了架构师?最近在开发一些通用的excel数据导入的功能,由于涉及到导入的模块很多,所以开发了一个比较通用的e ... [详细]
  • 初识java关于JDK、JRE、JVM 了解一下 ... [详细]
  • 开发笔记:MyBatis学习之逆向工程
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了MyBatis学习之逆向工程相关的知识,希望对你有一定的参考价值。转载:http://w ... [详细]
author-avatar
心雨00937
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有