赞
踩
zygote由java编写而成,不能直接由init进程启动运行。若想执行zygote类,必须先创建虚拟机,然后在虚拟机上运行ZygoteInit类。执行这一任务的就是app_process程序。 下面我们开始分析zygote进程的启动流程: /system/core/rootdir/init.rc
可以看到init.rc中有如下导包
import /init.$(ro.zygote).rc
如果是64位系统,$(ro.zygote)的值为"zygote64" /system/core/rootdir/init.zygote64.rc
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
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
app_process64程序的main函数入口如下: frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[]) { ...... AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); ...... // Parse runtime arguments. Stop at first unrecognized option. bool zygote = false; bool startSystemServer = false; ...... while (i < argc) { const char* arg = argv[i++]; if (strcmp(arg, "--zygote") == 0) { zygote = true; } else if (strcmp(arg, "--start-system-server") == 0) { startSystemServer = true; } ...... } ...... if (zygote) { //zygote进程 runtime.start("com.android.internal.os.ZygoteInit", args, zygote); } else if (className) { //普通java进程 runtime.start("com.android.internal.os.RuntimeInit", args, zygote); } }
如果是zygote进程就走ZygoteInit代码,如果是普通java进程就走RuntimeInit代码,例如常用的am命令,/system/bin/am实际上是一个shell脚本,查看里面的代码可知是通过app_process来启动普通java进程,然后和AMS进行通信。
这里AppRuntime继承自AndroidRuntime,所以看到AndroidRuntime的start方法
frameworks/base/core/jni/AndroidRuntime.cpp
//AppRuntime继承自AndroidRuntime void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) { /* start the virtual machine */ JniInvocation jni_invocation; // ① 加载指定的虚拟机的库(art或者dalvik) jni_invocation.Init(NULL); JNIEnv* env; // ② 创建java虚拟机 if (startVm(&mJavaVM, &env, zygote) != 0) { return; } // ③ 注册JNI函数 if (startReg(env) < 0) { return; } ...... // ④ 正式进入java的世界,调用ZygoteInit.java的main方法 jclass startClass = env->FindClass(slashClassName); ...... jmethodID startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V"); ...... env->CallStaticVoidMethod(startClass, startMeth, strArray); ...... }
①: 加载虚拟机的库(art或者dalvik),并且函数指针指向库对应的函数(如:JNI_CreateJavaVM函数) libnativehelper/JniInvocation.cpp
bool JniInvocation::Init(const char* library) {
//获取要加载库的名称
library = GetLibrary(library, buffer);
//动态加载对应的虚拟机库
handle_ = dlopen(library, RTLD_NOW);
......
//JNI_CreateJavaVM_函数指针指向虚拟机库中的JNI_CreateJavaVM函数
if (!FindSymbol(reinterpret_cast<void**>(&JNI_CreateJavaVM_),
"JNI_CreateJavaVM")) {
return false;
}
.......
return true;
}
GetLibraray()函数获取动态库的名称(libart.so或者libdalvik .so),dlopen()函数动态加载虚拟机库,RTLD_NOW表示返回之前立即链接所有未定位的符号,FindSysmbol()函数指针指向对应的函数。
函数说明: dlopen以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程,dlerror返回出现的错误,dlsym通过句柄和连接符名称获取函数名或者变量名,dlclose来卸载打开的库。 dlopen打开模式如下:
RTLD_LAZY 暂缓决定,等有需要时再解出符号 RTLD_NOW 立即决定,返回前解除所有未决定的符号。
dlclose(handle);关闭动态链接库
bool JniInvocation::FindSymbol(void** pointer, const char* symbol) {
*pointer = dlsym(handle_, symbol);
if (*pointer == NULL) {
ALOGE("Failed to find symbol %s: %s\n", symbol, dlerror());
dlclose(handle_);
handle_ = NULL;
return false;
}
return true;
}
libnativehelper/JniInvocation.cpp
static const char* kLibrarySystemProperty = "persist.sys.dalvik.vm.lib.2"; static const char* kDebuggableSystemProperty = "ro.debuggable"; static const char* kDebuggableFallback = "0"; // Not debuggable. static const char* kLibraryFallback = "libart.so"; const char* JniInvocation::GetLibrary(const char* library, char* buffer, bool (*is_debuggable)(), int (*get_library_system_property)(char* buffer)) { #ifdef __ANDROID__ const char* default_library; //如果不是debug设备,library的值为"libart.so" if (!is_debuggable()) { // Not a debuggable build. // Do not allow arbitrary library. Ignore the library parameter. This // will also ignore the default library, but initialize to fallback // for cleanliness. library = kLibraryFallback; default_library = kLibraryFallback; } else { // Debuggable build. // Accept the library parameter. For the case it is NULL, load the default // library from the system property. if (buffer != NULL) { if (get_library_system_property(buffer) > 0) { default_library = buffer; } else { default_library = kLibraryFallback; } } else { // No buffer given, just use default fallback. default_library = kLibraryFallback; } } #else UNUSED(buffer); UNUSED(is_debuggable); UNUSED(get_library_system_property); const char* default_library = kLibraryFallback; #endif if (library == NULL) { library = default_library; } return library; }
bool IsDebuggable() {
#ifdef __ANDROID__
char debuggable[PROP_VALUE_MAX] = {0};
__system_property_get("ro.debuggable", debuggable);
return strcmp(debuggable, "1") == 0;
#else
return false;
#endif
}
②: 创建java虚拟机 frameworks/base/core/jni/AndroidRuntime.cpp
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote) { JavaVMInitArgs initArgs; ...... initArgs.version = JNI_VERSION_1_4; initArgs.options = mOptions.editArray(); initArgs.nOptions = mOptions.size(); initArgs.ignoreUnrecognized = JNI_FALSE; ...... //创建java虚拟机 if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) { ALOGE("JNI_CreateJavaVM failed\n"); return -1; } return 0; }
JNI_CreateJavaVM()是JniInvocation.cpp中的函数,会调用到①中所说的JNI_CreateJavaVM_()函数指针,最后调用到相应虚拟机动态库中的JNI_CreateJavaVM()函数,创建对应的虚拟机。initArgs表示传入的虚拟机参数。
C/C++预处理指令,常见的预处理指令如下:
#空指令,无任何效果
#include包含一个源代码文件
#define定义宏
#undef取消已定义的宏
#if如果给定条件为真,则编译下面代码
#ifdef如果宏已经定义,则编译下面代码
#ifndef如果宏没有定义,则编译下面代码
#elif如果前面的#if给定条件不为真,当前条件为真,则编译下面代码
#endif结束一个#if……#else条件编译块
#error停止编译并显示错误信息
③: 注册JNI本地函数 我们先来熟悉一下几个数据结构: frameworks/base/core/jni/AndroidRuntime.cpp
#define REG_JNI(name) { name }
struct RegJNIRec {
int (*mProc)(JNIEnv*);
};
......
static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_os_RuntimeInit),
REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
REG_JNI(register_android_os_SystemClock),
REG_JNI(register_android_util_EventLog),
REG_JNI(register_android_util_Log),
......
};
gRegJNI是RegJNIRec结构体数组,然后数组通过REG_JNI宏定义初始化。例如gRegJNI第一个元素的初始化,等同于:
gRegJNI[0] = {register_com_android_internal_os_RuntimeInit};
那么gRegJNI[0]中RegJNIRec结构体的mProc函数指针就指向上面的函数register_com_android_internal_os_RuntimeInit,数组中的其它元素也同理。下面我们继续分析JNI本地函数的注册。
frameworks/base/core/jni/AndroidRuntime.cpp
int AndroidRuntime::startReg(JNIEnv* env) { ...... //注册JNI本地函数,将gRegJNI数组传入 if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) { return -1; } ...... return 0; } static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env) { //遍历执行gRegJNI数组中元素的mProc函数 //(mProc是函数指针,数组初始化的时候已经指向指定的函数) for (size_t i = 0; i < count; i++) { if (array[i].mProc(env) < 0) { return -1; } } return 0; }
startReg会调用register_jni_procs遍历调用gRegJNI数组中的mProc函数,以第一个元素为例,gRegJNI[0].mProc(env)由上面的分析可知调用的实际是register_com_android_internal_os_RuntimeInit(env)函数。
frameworks/base/core/jni/AndroidRuntime.cpp
int register_com_android_internal_os_RuntimeInit(JNIEnv* env)
{
const JNINativeMethod methods[] = {
{ "nativeFinishInit", "()V",
(void*) com_android_internal_os_RuntimeInit_nativeFinishInit },
......
};
//最后会调用到(*env)->RegisterNative()注册
return jniRegisterNativeMethods(env, "com/android/internal/os/RuntimeInit",
methods, NELEM(methods));
}
用上面的代码可知,nativeFinishInit函数映射了com_android_internal_os_RuntimeInit_nativeFinishInit函数,当java调用nativeFinishInit函数时,实际会调用到c/c++中的com_android_internal_os_RuntimeInit_nativeFinishInit函数。有读者可能会问,java调用jni函数时,虚拟机会自动映射,为什么要自己映射呢?如果jni函数比较少,这么做确实可行,但是我们可以看到gRegJNI数组是很庞大的,需要映射的函数也很多,如果全部交给虚拟机映射,会大大降低虚拟机的执行性能,所以我们提前注册JNI函数,虚拟机就可以直接找到对应的函数进行调用。
④: 通过反射调用ZygoteInit.java的main函数,正式进入java的世界。env->FindClass获取ZygoteInit类的类型,env->GetStaticMethodID获取函数main的函数id,env->CallStaticVoidMethod调用ZygoteInit.java的静态函数main。
至此,我们已经创建好了虚拟机,并且将ZygoteInit类装载到了虚拟机。接下来,ZygoteInit类将会被运行,那么ZygoteInit类具体有哪些功能呢?大致概括为如下几点:
绑定套接字,用来接收新Android应用程序运行请求
预加载Android Application Framework 使用的类与资源
启动并运行SystemServer
处理新Android应用程序运行请求
ZygoteInit的main函数: frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) { ZygoteServer zygoteServer = new ZygoteServer(); ...... try{ boolean startSystemServer = false; String socketName = "zygote";//套接字默认名称zygote for (int i = 1; i < argv.length; i++) { if ("start-system-server".equals(argv[i])) { startSystemServer = true; } ...... } // ① 绑定/dev/socket/zygote套接字,用来接收Android应用程序运行请求 zygoteServer.registerServerSocketFromEnv(socketName); ...... if (!enableLazyPreload) { ...... // ② 预加载类与资源 preload(bootTimingsTraceLog); ...... } ...... if (startSystemServer) { // ③ fork出system_server子进程 Runnable r = forkSystemServer(abiList, socketName, zygoteServer); // ③ {@code r == null}表示是父进程(zygote),{@code r != null}在子进程(system_server) if (r != null) { // ③ 如果是子进程(system_server)就执行run()方法,并返回,父进程(zygote)就继续往下执行 r.run(); return; } } Log.i(TAG, "Accepting command socket connections"); // ④ 这轮询会在zygote进程中无限循环,而fork出的子进程(Android应用进程)会退出来 caller = zygoteServer.runSelectLoop(abiList); } catch (Throwable ex) { Log.e(TAG, "System zygote died with exception", ex); throw ex; } finally { //system_server进程和android应用进程会关闭socket,zygote仍然在runSelectLoop中轮询监听socket zygoteServer.closeServerSocket(); } // ④ Android应用进程会走到这儿,执行相应的命令 if (caller != null) { caller.run(); } }
①: 绑定套接字,用来接收运行Android应用运行请求 frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
void registerServerSocketFromEnv(String socketName) { if (mServerSocket == null) { int fileDesc; //fullSocketName为“ANDROID_SOCKET_zygote” final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName; try { //获取ANDROID_SOCKET_zygote的坏境变量(即为/dev/socket/zygote的文件描述符的值) //是init进程在启动zygote进程时保存到环境变量中的 String env = System.getenv(fullSocketName); fileDesc = Integer.parseInt(env); } catch (RuntimeException ex) { throw new RuntimeException(fullSocketName + " unset or invalid", ex); } try { //绑定socket,在后面用来接收Android应用启动请求 FileDescriptor fd = new FileDescriptor(); fd.setInt$(fileDesc); mServerSocket = new LocalServerSocket(fd); mCloseSocketFd = true; } catch (IOException ex) { ...... } } }
②: 预加载类和资源,后面从zygote进程fork出的应用进程可以直接共享,加快应用进程启动速度。 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
static void preload(TimingsTraceLog bootTimingsTraceLog) {
......
preloadClasses();
......
preloadResources();
......
nativePreloadAppProcessHALs();
......
preloadOpenGL();
preloadSharedLibraries();
preloadTextResources();
.......
}
③: forkSystemServer fork出system_server子进程,并返回可以调用SystemServer中main方法的Runnable r,并执行对应的run方法,而父进程zygote则继续往下执行runSelectLoop,监听Android应用运行执行请求。
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) { ...... /* Hardcoded command line to start the system server */ String args[] = { "--setuid=1000", //用户id "--setgid=1000", //组id ...... "--nice-name=system_server", ...... "com.android.server.SystemServer", }; ZygoteConnection.Arguments parsedArgs = null; int pid; try { parsedArgs = new ZygoteConnection.Arguments(args); ...... //fork出system_server子进程,并且设置对应的参数 pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.runtimeFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } //子进程(system_server) if (pid == 0) { ...... //所以返回的r不为null,直接执行r.run return handleSystemServerProcess(parsedArgs); } //父进程(zygote),返回的是null,继续往下执行 return null; }
ZygoteInit的forkSystemServer方法会调用Zygote的forkSystemServer方法,如果是子进程(system_server)就返回handleSystemServerProcess(),父进程(zygote)就返回null。 frameworks/base/core/java/com/android/internal/os/Zygote.java
public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
......
int pid = nativeForkSystemServer(uid, gid, gids, runtimeFlags,
rlimits, permittedCapabilities, effectiveCapabilities);
......
return pid;
}
调用nativeForkSystemServer fork出子进程,nativeForkSystemServer是本地方法,在前面已经通过startReg方法中的register_com_android_internal_os_Zygote将nativeForkSystemServer方法映射到com_android_internal_os_Zygote_nativeForkSystemServer方法上
fork出子进程之后,子进程就开始调用handleSystemServerProcess()方法 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) { ...... //从环境变量SYSTEMSERVERCLASSPATH获取到SystemServer类文件相应jar包的路径 final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); if (systemServerClasspath != null) { //对相应的jar包做dex优化处理 performSystemServerDexOpt(systemServerClasspath); ...... } ...... ClassLoader cl = null; if (systemServerClasspath != null) { //创建类加载器classloader cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion); Thread.currentThread().setContextClassLoader(cl); } return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); }
先从SYSTEMSERVERCLASSPATH环境中获取到SystemServer的classpath,然后使用performSystemServerDexOpt对classpath对应的jar包做dex优化处理。然后创建对应的classloader,后续用来加载SystemServer类,ZygoteInit.zygoteInit()继续往下执行: frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
......
//将标准输出流和标准错误流重定向到Android log中
RuntimeInit.redirectLogStreams();
......
//本地方法,startReg映射,主要是开启ProcessState线程池,用来进行binder通信
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
redirectLogStreams会将标准输入,错误流重定位到Android log中,nativeZygoteInit JNI函数(startReg映射)会开启ProcessState线程池,用来进行binder通信。
继续往下执行RuntimeInit.applicationInit(): frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,ClassLoader classLoader) {
......
// Remaining arguments are passed to the start class's static main
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
继续往下执行:
/** * Invokes a static "main(argv[]) method on class "className". * Converts various failing exceptions into RuntimeExceptions, with * the assumption that they will then cause the VM instance to exit. * * @param className Fully-qualified class name * @param argv Argument vector for main() * @param classLoader the classLoader to load {@className} with */ protected static Runnable findStaticMain(String className, String[] argv,ClassLoader classLoader) { Class<?> cl; ...... //获取到SystemServer的类类型 cl = Class.forName(className, true, classLoader); ...... Method m; try { //获取到main方法的方法id m = cl.getMethod("main", new Class[] { String[].class }); } catch (NoSuchMethodException ex) { ...... } catch (SecurityException ex) { ...... } //这个就是③中forkSystemServer的返回值r return new MethodAndArgsCaller(m, argv); }
findStaicMain获取到SystemServer的类类型,并且获取到SystemServer中的main方法的方法id。然后new MethodAndArgsCaller(m,argv)就是③中forkSystemServer的返回值r,让我们看看r.run做了一些什么。 frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
static class MethodAndArgsCaller implements Runnable { /** method to call */ private final Method mMethod; /** argument array */ private final String[] mArgs; public MethodAndArgsCaller(Method method, String[] args) { mMethod = method; mArgs = args; } public void run() { try { //通过反射调用mMethod静态方法 mMethod.invoke(null, new Object[] { mArgs }); } catch (IllegalAccessException ex) { ...... } catch (InvocationTargetException ex) { ...... } } }
由上可知,就是通过反射执行SystemServer类的main方法。众所周知,system_server进程注册和运行着AMS、PMS、PKMS等核心系统服务
④: zygoteServer.runSelectLoop()这轮询会在zygote进程中无限循环,而fork出的子进程(Android应用进程)会退出并继续往下执行
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
//开启zygote进程轮询监听。接收新的socket连接(会创建新的ZygoteConnection) //并且从这些链接中中读取命令,并且执行 Runnable runSelectLoop(String abiList) { ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>(); ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>(); fds.add(mServerSocket.getFileDescriptor()); peers.add(null); while (true) { StructPollfd[] pollFds = new StructPollfd[fds.size()]; for (int i = 0; i < pollFds.length; ++i) { pollFds[i] = new StructPollfd(); pollFds[i].fd = fds.get(i); pollFds[i].events = (short) POLLIN; } try { //开启轮询 Os.poll(pollFds, -1); } catch (ErrnoException ex) { throw new RuntimeException("poll failed", ex); } for (int i = pollFds.length - 1; i >= 0; --i) { if ((pollFds[i].revents & POLLIN) == 0) { continue; } if (i == 0) {//如果是新的socket链接请求(建立新连接) //新建ZygoteConnection链接 ZygoteConnection newPeer = acceptCommandPeer(abiList); //添加到链接数组中 peers.add(newPeer); //添加到文件描述符数组中 fds.add(newPeer.getFileDesciptor()); } else {//如果是之前已经建立的socket链接(在已有连接上) try { //获取对应的ZygoteConnection ZygoteConnection connection = peers.get(i); //会执行ZygoteConnection发送过来的命令 final Runnable command = connection.processOneCommand(this); if (mIsForkChild) {//子进程走这儿 ...... //退出,command就是④中的caller return command; } else {//父进程走这儿,上面是while无限循环,zygote进程永远不会退出 ...... if (connection.isClosedByPeer()) { connection.closeSocket(); peers.remove(i); fds.remove(i); } } } catch (Exception e) { ...... } finally { mIsForkChild = false; } } } } }
上面的流程概括来说,就是会轮询/dev/socket/zygote的socket,如果有新的链接,就新建ZygoteConnection,并将对应的socket fd添加到fds(轮询数组中),继续轮询,如果是新的链接,就重复上面的操作,如果是已经建立的链接,就执行该链接上读取到的command,也就是connection.processOneCommand()方法。
Android P之前processOneCommand的方法名是runOnce
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) { String args[]; Arguments parsedArgs = null; FileDescriptor[] descriptors; try { //读取命令 args = readArgumentList(); descriptors = mSocket.getAncillaryFileDescriptors(); } catch (IOException ex) { ...... } ...... parsedArgs = new Arguments(args); ...... //fork子进程 pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo, parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote, parsedArgs.instructionSet, parsedArgs.appDataDir); try { if (pid == 0) { // 子进程中(应用进程中) zygoteServer.setForkChild(); ...... return handleChildProc(parsedArgs, descriptors, childPipeFd, parsedArgs.startChildZygote); } else { //父进程中(zygote) ...... return null; } } finally { ...... } }
从当前链接socket中读取启动命令。如果读取成功,zygote将会fork出子进程,并且返回可以调用启动类的main方法的runnable(也就是④中的caller)
zygoteServer.setForkChild()将mIsForkChild全局变量设为true。 我们接下来分析handleChildProc()方法 frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,FileDescriptor pipeFd, boolean isZygote) {
//关闭ZygoteConnection中的socket链接
closeSocket();
......
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}
......
if (!isZygote) {
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,null /* classLoader */);
} else {
......
}
}
从ZygoteInit.zygoteInit()开始就和③中分析的代码一模一样了,这里就不重复分析了,③中返回的是可以调用SystemServer的main方法的Runnable,而④中返回的是可以调用ActivityThread的main方法的Runnable。
上面我们提到Zygote进程是第一个java进程,但整篇分析下来,java进程其实也是运行在c++进程之上的,只不过是java虚拟机屏蔽了这一切。zygote进程的启动,是从c++世界一步一步过渡到java世界,每个世界做了自己的准备工作。
更多的Framework学习资料可以扫码免费领取!
● 第一节 Android系统结构
● 第二节 Android是怎么启动的
● 第三节 Android 11.0系统启动之init进程
● 第四节 Android11.0系统启动之Zygote进程
● 第五节 Android 11.0 系统启动之SystemServer进程
● 第六节 Android 11.0 系统服务之ActivityMnagerService-AMS启动流程
● 第七节 Android11.0系统启动之Launcher(桌面)启动流程
● 第八节 Android11.0应用进程创建过程以及Zygote的fork流程
● 第九节 Android 11.0 PackageManagerService(一)工作原理及启动流程
● 第十节 Android 11.0 PackageManagerService-APK安装流程
● 第一节 Android11.0 日志系统分析-logd、logcat 指令说明、分类和属性
● 第一节 Android11.0 Binder通信原理(一)Binder、HwBinder、VndBinder概要
● 第二节 Android11.0 Binder通信原理(二)-Binder入门篇
● 第三节 Android11.0 Binder通信原理(三)-ServiceManager篇
● 第四节 Android11.0 Binder通信原理(四)-Native-C\C++实例分析
● 第五节 Android11.0 Binder通信原理(五)-Binder驱动分析
● 第六节 Android11.0 Binder通信原理(六)-Binder数据如何完成定向打击
● 第七节 Android11.0 Binder通信原理(七)-Framework binder示例
● 第八节 Android11.0 Binder通信原理(八)-Framework层分析
● 第九节 Android11.0 Binder通信原理(九)-AIDL Binder示例
● 第十节 Android11.0 Binder通信原理(十)-AIDL原理分析-Proxy-Stub设计模式
● 第十一节 Android11.0 Binder通信原理(十一)-Binder总结
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。