本篇文章主要介绍 Android Zygote 启动分析 知识点,经过阅读本篇文章,您将收获如下内容:java
1、 Android 系统基本服务
2、虚拟机建立和第一个Java 程序引导
3、Dalvik 虚拟机基本配置
4、Zygote 启动流程
5、Zygote 启动分析
6、Zygote 建立system_server主要方法
7、Zygote 建立System_server 分析
8、Zygote 建立应用
9、Zygote 建立应用流程
10、Zygote 预加载资源
11、Zygote 预加载的目的
12、优化Zygote 启动方法: 线程池
十3、fork SystemServer
Zygote
服务时经过 init.rc
进程启动的,Zygote
的 classname
为main
.init.rc
文件配置代码以下:android
... ... on nonencrypted class_start main class_start late_start on property:sys.init_log_level=* loglevel ${sys.init_log_level} ... ...
详细能够参考 init.rc
启动分析。
Android 9.0 init 启动流程程序员
app_main.cpp
是Zygote
进程的main
函数,frameworks\base\cmds\app_process\app_main.cpp
微信
Android
系统包含netd
、servicemanager
、surfaceflinger
、zygote
、media
、installd
、bootanimation
等基本服务,具体做用请看下图。多线程
为了让APK
在不一样的虚拟机均可以运行,Google
采起了适配器模式,在让虚拟机运行以前先执行 dexopt
,即将dex
文件优化成odex
文件,可让虚拟机更加优化的执行。app
在ART
虚拟机中,dexopt
将dex
文件优化成二进制格式的问题,从而可让ART
虚拟机执行。dexopt
会调用dex2oat
进行优化,dex2oat
的任务是将原来的dex
文件进行预翻译,从而能够加快app
运行的时间,可是因为某些app
比较复杂,因此优化的时间就比较长。
优化是以dex
文件中的Method
方法为单位,dex2oat
在优化时候,会根据需求优化必定量的Method
,即不是全部的Method
都回翻译成oat
模式。socket
在Android
系统中,Dalvik
虚拟机 和ART
、应用程序进程,以及运行系统的关键服务SystemServer
进程都是由 Zygote
进程建立孵化的。ide
Dalvik 虚拟机基本配置以下:函数
Zygote
是由 init.rc
脚本启动,在init
脚本中,咱们能够看到会导入import /init.${ro.zygote}.rc
脚本优化
# Copyright (C) 2012 The Android Open Source Project # # IMPORTANT: Do not create world writable files or directories. # This is a common source of Android security bugs. # import /init.environ.rc import /init.usb.rc import /init.${ro.hardware}.rc import /vendor/etc/init/hw/init.${ro.hardware}.rc import /init.usb.configfs.rc ... ... import /init.${ro.zygote}.rc ... ...
在 system/core/rootdir
目录下,会根据ro.zygote
属性值不一样,启动不一样的脚本,主要包含如下四个zygote
脚本。
Zygote 启动优化前提:
Android
提供了Executors
和ExecutorService
多线程类,所以可使用多线程来加载类和资源。Zygote 启动优化实质:
使咱们的进程最大限度的抢占CPU
通过一系列初始化后,在ZygoteInit
类中 forkSystemServer
,为启动SystemServer
作准备。ZygoteInit.java
代码路径以下:alps\frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
/** * Prepare the arguments and forks for the system server process. * * Returns an {@code Runnable} that provides an entrypoint into system_server code in the * child process, and {@code null} in the parent. */ private static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) { long capabilities = posixCapabilitiesAsBits( OsConstants.CAP_IPC_LOCK, OsConstants.CAP_KILL, OsConstants.CAP_NET_ADMIN, OsConstants.CAP_NET_BIND_SERVICE, OsConstants.CAP_NET_BROADCAST, OsConstants.CAP_NET_RAW, OsConstants.CAP_SYS_MODULE, OsConstants.CAP_SYS_NICE, OsConstants.CAP_SYS_PTRACE, OsConstants.CAP_SYS_TIME, OsConstants.CAP_SYS_TTY_CONFIG, OsConstants.CAP_WAKE_ALARM, OsConstants.CAP_BLOCK_SUSPEND ); /* Containers run without some capabilities, so drop any caps that are not available. */ StructCapUserHeader header = new StructCapUserHeader( OsConstants._LINUX_CAPABILITY_VERSION_3, 0); StructCapUserData[] data; try { data = Os.capget(header); } catch (ErrnoException ex) { throw new RuntimeException("Failed to capget()", ex); } capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32); /* Hardcoded command line to start the system server */ String args[] = { "--setuid=1000", "--setgid=1000", /// M: [Wi-Fi Hotspot Manager] system_server add dhcp (1014) group to access /// "/data/misc/dhcp/dnsmasq.leases" "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1014,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", }; ZygoteConnection.Arguments parsedArgs = null; int pid; try { parsedArgs = new ZygoteConnection.Arguments(args); ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); boolean profileSystemServer = SystemProperties.getBoolean( "dalvik.vm.profilesystemserver", false); if (profileSystemServer) { parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER; } /* Request to fork the system server process */ pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.runtimeFlags, 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(); return handleSystemServerProcess(parsedArgs); } return null; }
至此,本篇已结束,若有不对的地方,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!