本文主要介绍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 可执行文件
priority -20
user root
group root readproc
socket zygote stream 660 root system---》创建/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 中的参数
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
从该函数 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". --->仔细看这里的说明
* Passes the main function two arguments, the class name and the specified
* options string.
*/
void AndroidRuntime::start(const char* className, const Vector& options, bool zygote)
{
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {----------》启动VM
return;
}
onVmCreated(env);
/*
* Register android functions.-------------》启动JNI 环境
*/
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中设定zygote 参数
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);------》加载系统资源
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 优先级
int pid = nativeForkSystemServer(---->进入naitive C++ 函数, 进行了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, 到底加载了哪些系统资源,共享资源进行预加载,独立的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()方法内部调用了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加载到系统中,生成字节码,系统启动过程需要一定时间
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 中layout 中的资源,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
下面是具体的参数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
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 创建了/dev/socket/zygote , 系统如何调用socket 创建通信, 在下面的文章中进行讲解registerServerSocket
zygoteInit::main--->
registerServerSocket--->
preload---->
forkSystemServer--->
总体概述:
https://www.cnblogs.com/monsterdev/p/12685091.html
https://blog.csdn.net/chz429/article/details/87514718