android开发基于Android10分析Zygote启动过程以及Fork应用进程的过程分析
android开发基于Android10分析Zygote启动过程以及Fork应用进程的过程分析
-
Zygote进程的启动,从c代码转到java代码的过程
- Android系统启动后第一个进程是init进程,init进程解析init.rc启动Zygote进程
- 如果是64位解析文件是init.zygote64.rc:system/core/rootdir/init.zygote64.rc
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote - 是的zygote进程其实就是一个可执行文件,这个文件就是app_process64(64位的,32位的是app_process32)
- app_process64可执行文件对应源代码app_main.cpp,也就是从这个文件的main方法跑起来了
frameworks/base/cmds/app_process/app_main.cpp - app_main.cpp文件的main方法定义了一个关键变量:AppRuntime runtime,然后调用runtime.start方法
int main(int argc, char* const argv[]) { AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); if (zygote) { runtime.start("com.android.internal.os.ZygoteInit", args, zygote); //调用start方法开启 } else if (className) { runtime.start("com.android.internal.os.RuntimeInit", args, zygote); } }
- AppRuntime继承于AndroidRuntime类,runtime.start方法的实现是AndroidRuntime::start
位于frameworks/base/core/jni/AndroidRuntime.cpp文件
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) { if (startVm(&mJavaVM, &env, zygote) != 0) { //开启java虚拟机 return; } if (startReg(env) < 0) { //注册jni函数 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. */ //将.替换为/,即将com.android.internal.os.ZygoteInit改为com/android/internal/os/ZygoteInit 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");//找到ZygoteInit的main方法 if (startMeth == NULL) { ALOGE("JavaVM unable to find main() in '%s'\n", className); } else { env->CallStaticVoidMethod(startClass, startMeth, strArray); //调用ZygoteInit的main方法,代码来到java层,但还是Zygote进程 } } }
-
Zygote进程java代码执行流程
- com.android.internal.os.ZygoteInit类的main方法执行起来
public static void main(String argv[]) { // Mark zygote start. This ensures that thread creation will throw an error. ZygoteHooks.startZygoteNoThreadCreation(); //做个标记,不准创建其他线程 preload(bootTimingsTraceLog); //预加载系统资源,包含系统常用类、资源、字体等等 ZygoteHooks.stopZygoteNoThreadCreation(); zygoteServer = new ZygoteServer(isPrimaryZygote); //创建一个SocketServer,用于后面监听应用启动fork if (startSystemServer) { //上面--start-system-server表示要启动SystemServer这个大儿子 Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer); // {@code r == null} in the parent (zygote) process, and {@code r != null} in the child (system_server) process. if (r != null) { r.run(); return; } } Log.i(TAG, "Accepting command socket connections"); // The select loop returns early in the child process after a fork and loops forever in the zygote. caller = zygoteServer.runSelectLoop(abiList);//socket监听App fork操作 //如果监听到了,runSelectLoop会返回子进程的caller,然后这里调用caller.run()让App跑起来 if (caller != null) { caller.run(); } }
- runSelectLoop方法分析,监听到App fork操作就返回子进程的Runnable,父进程继续循环监听
Runnable runSelectLoop(String abiList) { while (true) { ... ZygoteConnection connection = peers.get(pollIndex); final Runnable command = connection.processOneCommand(this); //处理子进程命令,设置mIsForkChild=true if (mIsForkChild) { return command; //子进程返回,退出while (true)循环 } else { //父进程继续while (true)监听 } } }
- processOneCommand方法分析,读取socket参数,fork子进程
Runnable processOneCommand(ZygoteServer zygoteServer) { args = Zygote.readArgumentList(mSocketReader); //从socket读取参数 ZygoteArguments parsedArgs = new ZygoteArguments(args); //调用parseArgs(args);分析参数 pid = Zygote.forkAndSpecialize();//fork子进程,native方法,内部实现就是c语言的fork函数调用 if (pid == 0) { //pid==0是子进程 zygoteServer.setForkChild();//标记为子进程,上面的mIsForkChild使用到 return handleChildProc(parsedArgs, descriptors, childPipeFd, parsedArgs.mStartChildZygote);//处理子进程逻辑 } else { //处理父进程逻辑 } }
- 接着调用handleChildProc处理子进程逻辑
//parsedArgs参数里有"android.app.ActivityThread"参数,App启动端通过socket发送的参数带有 //具体位置final String entryPoint = "android.app.ActivityThread"; startProcessLocked(... entryPoint ...) 1. handleChildProc(parsedArgs, descriptors, childPipeFd, parsedArgs.mStartChildZygote) //调用commonInit,设置了全局KillApplicationHandler等等 2. ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion, parsedArgs.mRemainingArgs, null /* classLoader */) //参数包括entryPoint继续通过argc传递下去 3. RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader) //找到android.app.ActivityThread的main方法,返回了new MethodAndArgsCaller(m, argv) //实际就是上面的runSelectLoop的返回值,所以caller.run()执行实际上是子进程的逻辑,就是调用了fork出来的子进程的ActivityThread类的main方法 4. RuntimeInit.findStaticMain(String className, String[] argv,ClassLoader classLoader)
- 接着就是App进程的ActivityThread类的main方法的执行了
//这个是普通进程的入口执行函数。还有一个方法systemMain是SystemServer进程的入口函数,调用链:SystemServer类->run->createSystemContext public static void main(String[] args) { ActivityThread thread = new ActivityThread();//ActivityThread就是一个普通java类,直接new一个 thread.attach(false, startSeq); Looper.loop();//App的主线程是不能退出的不然APP就崩溃了,就是这句话起作用,一直在loop。。 } private void attach(boolean system, long startSeq) { final IActivityManager mgr = ActivityManager.getService(); //binder通信,调用ActivityManagerService的attachApplication方法 try { mgr.attachApplication(mAppThread, startSeq); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } }
- 接下来进入SystemServer进程的ActivityManagerService的attachApplication方法
//ActivityManagerService是跑在SystemServer进程的!!这个知道吧 public final void attachApplication(IApplicationThread thread, long startSeq) { ... thread.bindApplication();//thread是App的代理对象,最后调用ActivityThread的bindApplication方法,回到App进程 } //通过ActivityThread的H这个hanlder转到handleBindApplication方法
- 接着又回到App进程了,执行handleBindApplication方法创建Application对象
private void handleBindApplication(AppBindData data) { app = data.info.makeApplication(data.restrictedBackupMode, null); mInstrumentation.callApplicationOnCreate(app);//执行Application的onCreate方法 }
下面是一些执行Zygote启动和fork子进程的一些堆栈信息记录:
attemptZygoteSendArgsAndGetResult: msgStr=14 --runtime-args --setuid=10093 --setgid=10093 --runtime-flags=10240 --mount-external-write --target-sdk-version=28 --setgroups=50093,20093,9997,3003 --nice-name=com.android.gallery3d --seinfo=default:targetSdkVersion=28:complete --instruction-set=arm64 --app-data-dir=/data/user/0/com.android.gallery3d --package-name=com.android.gallery3d //包括 android.app.ActivityThread //主类入口 seq=52 attemptZygoteSendArgsAndGetResult=java.lang.Throwable at android.os.ZygoteProcess.attemptZygoteSendArgsAndGetResult(ZygoteProcess.java:428) //App发送fork请求,最终走这个方法 at android.os.ZygoteProcess.zygoteSendArgsAndGetResult(ZygoteProcess.java:419) at android.os.ZygoteProcess.startViaZygote(ZygoteProcess.java:636) at android.os.ZygoteProcess.start(ZygoteProcess.java:333) at android.os.Process.start(Process.java:534) //Process.start是Android系统修改过的实现,主要是调用Zygote进行fork at com.android.server.am.ProcessList.startProcess(ProcessList.java:1823) at com.android.server.am.ProcessList.lambda$startProcessLocked$0$ProcessList(ProcessList.java:1668) at com.android.server.am.-$$Lambda$ProcessList$vtq7LF5jIHO4t5NE03c8g7BT7Jc.run(Unknown Source:20) at android.os.Handler.handleCallback(Handler.java:883) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loop(Looper.java:214) at android.os.HandlerThread.run(HandlerThread.java:67) at com.android.server.ServiceThread.run(ServiceThread.java:44) forkAndSpecialize: java.lang.Throwable at com.android.internal.os.Zygote.forkAndSpecialize(Zygote.java:241) //fork完子进程后继续循环监听,所以不再走下去了 at com.android.internal.os.ZygoteConnection.processOneCommand(ZygoteConnection.java:267) at com.android.internal.os.ZygoteServer.runSelectLoop(ZygoteServer.java:456) //Zygote进程调用runSelectLoop方法 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:931) //Zygote进程 handleChildProc: parsedArgs.mInvokeWith=null handleChildProc: parsedArgs.mNiceName=com.android.gallery3d findStaticMain: className=android.app.ActivityThread findStaticMain: argv=seq=52 findStaticMain:java.lang.Throwable at com.android.internal.os.RuntimeInit.findStaticMain(RuntimeInit.java:290) //查找ActivityThread的main方法进行执行 at com.android.internal.os.RuntimeInit.applicationInit(RuntimeInit.java:368) at com.android.internal.os.ZygoteInit.zygoteInit(ZygoteInit.java:997) at com.android.internal.os.ZygoteConnection.handleChildProc(ZygoteConnection.java:601) //处理子进程的逻辑 at com.android.internal.os.ZygoteConnection.processOneCommand(ZygoteConnection.java:281) at com.android.internal.os.ZygoteServer.runSelectLoop(ZygoteServer.java:456) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:931) //Zygote执行fork得到的子进程 ActivityThreadMain: seq=52 ActivityThreadMain: java.lang.Throwable at android.app.ActivityThread.main(ActivityThread.java:7313) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:497) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:944)