本文主要介紹zygote 流程
frameworks/base/cmds/app_process/app_main.cpp
frameworks/base/core/jni/AndroidRuntime.cpp
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
frameworks/base/core/java/com/android/internal/os/Zygote.java
1 皱埠, 解析zygote 腳本故黑,并運行main
android/system/core/rootdir/init.zygote64.rc
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main --> 啟動app_process 可執(zhí)行文件
priority -20
user root
group root readproc
socket zygote stream 660 root system---》創(chuàng)建/dev/socket/zygote
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{
while (i < argc) { -----》解析zygote rc 中的參數(shù)
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
}
...........
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);---->啟動zygote
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
}
}
2 啟動VM JNI
從該函數(shù) cpp-->java 啟動java虛擬機
frameworks/base/core/jni/AndroidRuntime.cpp
/*
* Start the Android runtime. This involves starting the virtual machine
* and calling the "static void main(String[] args)" method in the class
* named by "className". --->仔細(xì)看這里的說明
* Passes the main function two arguments, the class name and the specified
* options string.
*/
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {----------》啟動VM
return;
}
onVmCreated(env);
/*
* Register android functions.-------------》啟動JNI 環(huán)境
*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
/*
* Start VM. This thread becomes the main thread of the VM, and will
* not return until the VM exits.
*/
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);---->啟動main , zygote init
}
}
3 注冊socket 加載資源 fork 等待
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
for (int i = 1; i < argv.length; i++) {------->保存init.rc中設(shè)定zygote 參數(shù)
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
zygoteServer.registerServerSocket(socketName);--------》注冊socket
preload(bootTimingsTraceLog);------》加載系統(tǒng)資源
if (startSystemServer) {---------->第一次首先fork SystemServer, SystemServer單獨講解
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
}
caller = zygoteServer.runSelectLoop(abiList);------》
-----》zygot 進入run selectloop. ---》connection.processOneCommand(this)----》forkAndSpecialize
}
frameworks/base/core/java/com/android/internal/os/Zygote.java
/**
* Special method to start the system server process. In addition to the
* common actions performed in forkAndSpecialize, the pid of the child
* process is recorded such that the death of the child process will cause
* zygote to exit.
*
* @param uid the UNIX uid that the new process should setuid() to after
* fork()ing and and before spawning any threads.
* @param gid the UNIX gid that the new process should setgid() to after
* fork()ing and and before spawning any threads.
* @param gids null-ok; a list of UNIX gids that the new process should
* setgroups() to after fork and before spawning any threads.
* @param debugFlags bit flags that enable debugging features.
* @param rlimits null-ok an array of rlimit tuples, with the second
* dimension having a length of 3 and representing
* (resource, rlim_cur, rlim_max). These are set via the posix
* setrlimit(2) call.
* @param permittedCapabilities argument for setcap()
* @param effectiveCapabilities argument for setcap()
*
* @return 0 if this is the child, pid of the child
* if this is the parent, or -1 on error.
*/
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
VM_HOOKS.preFork();
// Resets nice priority for zygote process.
resetNicePriority();--->rest 優(yōu)先級
int pid = nativeForkSystemServer(---->進入naitive C++ 函數(shù), 進行了fork
uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
if (pid == 0) {
Trace.setTracingEnabled(true, debugFlags);
}
VM_HOOKS.postForkCommon();
return pid;
}
4 資源加載解析preload
啟動過程中使用到了preload, 到底加載了哪些系統(tǒng)資源,共享資源進行預(yù)加載搀崭,獨立的app運行粗卜,基本是使用過程加載。在preload整個過程中是禁止多線程桥爽。
static void preload(TimingsTraceLog bootTimingsTraceLog) {
Log.d(TAG, "begin preload");
preloadClasses(); ------》加載class
preloadResources(); ---->加載resource
nativePreloadAppProcessHALs(); ---->加載 APP hal resource
preloadOpenGL(); ---->加載openGL 資源
preloadSharedLibraries();---->加載共享庫
preloadTextResources();---->加載Text 資源
}
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
preloadClasses:基本思路朱灿,是讀取,while line by line , 解析加載钠四。
private static String PRELOADED_CLASSES = "/system/etc/preloaded-classes";-->class 路徑
InputStream is = new FileInputStream(PRELOADED_CLASSES); --》讀取流
BufferedReader br = new BufferedReader(new InputStreamReader(is), 256); -->讀取到buf
while ((line = br.readLine()) != null) { ---->line讀取
try {
// Load and explicitly initialize the given class. Use
// Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
// (to derive the caller's class-loader). Use true to force initialization, and
// null for the boot classpath class-loader (could as well cache the
// class-loader of this class in a variable).
Class.forName(line, true, null);------》上面解析基本說明了盗扒,class.forName()方法內(nèi)部調(diào)用了this.getClass().getClassLoader()方法
count++;
} catch (ClassNotFoundException e) {
}
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
frameworks/base/config/ preloaded-classes
只列舉部分的class , 因此通過Class.forName加載到系統(tǒng)中,生成字節(jié)碼缀去,系統(tǒng)啟動過程需要一定時間
android.R$styleable
android.accessibilityservice.AccessibilityServiceInfo$1
android.accounts.Account
android.accounts.Account$1
android.accounts.AccountManager
android.accounts.AccountManager$1
android.accounts.AccountManager$11
android.accounts.AccountManager$AmsTask
android.accounts.AccountManager$AmsTask$1
android.accounts.AccountManager$AmsTask$Response
android.accounts.AccountManager$BaseFutureTask
android.accounts.AccountManager$BaseFutureTask$1
android.accounts.AccountManager$BaseFutureTask$Response
android.accounts.AccountManager$Future2Task
android.accounts.AccountManagerFuture
............
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
preloadResources:
/**
* Load in commonly used resources, so they can be shared across
* processes.
*
* These tend to be a few Kbytes, but are frequently in the 20-40K
* range, and occasionally even larger.
*/
private static void preloadResources() {
final VMRuntime runtime = VMRuntime.getRuntime();
try {
mResources = Resources.getSystem();
mResources.startPreloading();
if (PRELOAD_RESOURCES) {
Log.i(TAG, "Preloading resources...");
long startTime = SystemClock.uptimeMillis();
TypedArray ar = mResources.obtainTypedArray(--------》加載
com.android.internal.R.array.preloaded_drawables);
int N = preloadDrawables(ar);
ar.recycle();
Log.i(TAG, "...preloaded " + N + " resources in "
+ (SystemClock.uptimeMillis()-startTime) + "ms.");
startTime = SystemClock.uptimeMillis();
ar = mResources.obtainTypedArray(--------》加載
com.android.internal.R.array.preloaded_color_state_lists);
N = preloadColorStateLists(ar);
ar.recycle();
Log.i(TAG, "...preloaded " + N + " resources in "
+ (SystemClock.uptimeMillis()-startTime) + "ms.");
if (mResources.getBoolean(--------》加載
com.android.internal.R.bool.config_freeformWindowManagement)) {
startTime = SystemClock.uptimeMillis();
ar = mResources.obtainTypedArray(---------》加載
com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
//preloaded_freeform_multi_window_drawables 路徑是:
frameworks/base/core/res/res/values/arrays.xml
上面的資源類似與apk 中l(wèi)ayout 中的資源侣灶,window窗口大小,包括app 窗口
N = preloadDrawables(ar);
ar.recycle();
Log.i(TAG, "...preloaded " + N + " resource in "
+ (SystemClock.uptimeMillis() - startTime) + "ms.");
}
}
mResources.finishPreloading();
} catch (RuntimeException e) {
Log.w(TAG, "Failure preloading resources", e);
}
}
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
preloadColorStateLists
下面是具體的參數(shù)TypedArray:
com.android.internal.R.array.preloaded_color_state_lists
private static int preloadColorStateLists(TypedArray ar) {
int N = ar.length();
for (int i=0; i<N; i++) {
int id = ar.getResourceId(i, 0);
if (false) {
Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
}
if (id != 0) {
if (mResources.getColorStateList(id, null) == null) {
throw new IllegalArgumentException(
"Unable to find preloaded color resource #0x"
+ Integer.toHexString(id)
+ " (" + ar.getString(i) + ")");
}
}
}
return N;
}
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
// Mark zygote start. This ensures that thread creation will throw an error.
ZygoteHooks.startZygoteNoThreadCreation(); -------->開始禁止多線程
registerServerSocket --->注冊socket
preload(bootTimingsTraceLog);--->加載資源
gcAndFinalize(); ---> // Do an initial gc to clean up after startup
ZygoteHooks.stopZygoteNoThreadCreation()-------->停止禁止多線程
Runnable r = forkSystemServer(abiList, socketName, zygoteServer)
}
4 zygote 的socket 通信
zygote 創(chuàng)建了/dev/socket/zygote , 系統(tǒng)如何調(diào)用socket 創(chuàng)建通信朵耕, 在下面的文章中進行講解registerServerSocket
zygoteInit::main--->
registerServerSocket--->
preload---->
forkSystemServer--->
總體概述:
https://www.cnblogs.com/monsterdev/p/12685091.html
https://blog.csdn.net/chz429/article/details/87514718