本篇文章主要介紹 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; }
至此,本篇已結束,若有不對的地方,歡迎您的建議與指正。同時期待您的關注,感謝您的閱讀,謝謝!