android开发基于Android10分析Zygote启动过程以及Fork应用进程的过程分析

android开发基于Android10分析Zygote启动过程以及Fork应用进程的过程分析

  1. 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进程
    		}
    	}
    
    }
    
  2. 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)
    
    
posted @ 2024-07-17 20:00  yongfengnice  阅读(21)  评论(0编辑  收藏  举报