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);
	}
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 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进程
		}
	}

}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  1. 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();
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 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)监听
			}
		}
	
	}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 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 {
		//处理父进程逻辑
	}
	
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 接着调用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)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 接着就是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();
	}
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 接下来进入SystemServer进程的ActivityManagerService的attachApplication方法
//ActivityManagerService是跑在SystemServer进程的!!这个知道吧
public final void attachApplication(IApplicationThread thread, long startSeq) {
	...
	thread.bindApplication();//thread是App的代理对象,最后调用ActivityThread的bindApplication方法,回到App进程
}

//通过ActivityThread的H这个hanlder转到handleBindApplication方法
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 接着又回到App进程了,执行handleBindApplication方法创建Application对象
private void handleBindApplication(AppBindData data) {
	app = data.info.makeApplication(data.restrictedBackupMode, null);
	mInstrumentation.callApplicationOnCreate(app);//执行Application的onCreate方法
}
  • 1.
  • 2.
  • 3.
  • 4.

下面是一些执行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)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.