应用的主线程和binder线程是如何启动的

kernel启动后,init进程会通过init rc配置脚本启动编译为app_process的二进制可执行文件,启动后的进程名为zygote。
zygote会启动虚拟机环境,然后fork出system_server进程,进入Java世界。
system_server是Android的系统进程,各大服务AMS、PMS、WMS等都运行在这个进程中。

1 system_server 进程发送fork请求

启动四大组件时,如果应用进程不存在,就会走到AMS创建应用进程的过程,这个进程是从zygote fork出来的。
frameworks/base/services/core/java/com/android/server/am/ProcessList.java

boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,  
		int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,  
		String seInfo, String requiredAbi, String instructionSet, String invokeWith,  
		long startTime) {
	...
	if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
		// 默认是异步启动
		mService.mProcStartHandler.post(() -> handleProcessStart(  
		     app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal,  
			 requiredAbi, instructionSet, invokeWith, startSeq));  
		return true;
	} else {
		// 启动进程
		final Process.ProcessStartResult startResult = startProcess(hostingRecord,  
				 entryPoint, app,
				 uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,  
				 requiredAbi, instructionSet, invokeWith, startTime);
		// 进程启动后的处理
		handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper, startSeq, false);
		...
	}
}

private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,  
		ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,  
		int mountExternal, String seInfo, String requiredAbi, String instructionSet,  
		String invokeWith, long startTime) {

	Process.ProcessStartResult startResult;
	if (hostingRecord.usesWebviewZygote()) {
		// 启动webview
	    startResult = startWebView(entryPoint,
				app.processName, uid, uid, gids, runtimeFlags, mountExternal,
				app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
				app.info.dataDir, null, app.info.packageName, app.mDisabledCompatChanges,
				new String[]{PROC_START_SEQ_IDENT + app.startSeq});
	} else if (hostingRecord.usesAppZygote()) {
	} else {
		startResult = mService.handlePreForkStartProcess(preforkArgs);  
		if (startResult == null) {
			// 启动进程
			startResult = Process.start(entryPoint,  
				 app.processName, uid, uid, gids, runtimeFlags, mountExternal,  
				 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,  
				 app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,  
				 isTopApp, app.mDisabledCompatChanges, pkgDataInfoMap,  
				 whitelistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,  
				 new String[]{PROC_START_SEQ_IDENT + app.startSeq});  
		}
	}
}

为了减轻AMS的压力,默认为异步启动,异步启动的过程和同步启动差不多。

创建过程就是向zygote发送指令并获得结果。

// frameworks/base/core/java/android/os/Process.java
start {
	// frameworks/base/core/java/android/os/ZygoteProcess.java
	start {
		startViaZygote {
			// 1 准备参数
			// 2 
			zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), zygotePolicyFlags, argsForZygote) {
				if (shouldAttemptUsapLaunch(zygotePolicyFlags, args)) {  
			        return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
			    }

				return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr); {
					// 发送指令
					zygoteWriter.write(msgStr);  
					zygoteWriter.flush();

					
					Process.ProcessStartResult result = new Process.ProcessStartResult();  
					result.pid = zygoteInputStream.readInt();  
					result.usingWrapper = zygoteInputStream.readBoolean();  
  
					if (result.pid < 0) {  
					    throw new ZygoteStartFailedEx("fork() failed");  
					}  
  
					return result;
				}
			}
		}
	}
}

2 zygote进程响应fork请求

zygote是由init进程启动的。
zygote启动后,进入com.android.internal.os.ZygoteInit的main方法

public static void main(String argv[]) {
	...
	if (startSystemServer) {
		// 启动system_server
		Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
		if (r != null) {
		    r.run(); 
			return;
		}
	}
	// 进入循环,等待fork请求
	caller = zygoteServer.runSelectLoop(abiList);

	...

	// fork后在子进程
	if (caller != null) {  
	    caller.run();  
	}
}

frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

Runnable runSelectLoop(String abiList) {
	...
	while (true) {
		...
		while (-pollIndex >= 0) {
		
			ZygoteConnection connection = peers.get(pollIndex);
			// 处理命令,fork进程
			final Runnable command = connection.processOneCommand(this);

			if (mIsForkChild) {
				return command;
			}
		}
	}
}
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) {
	// fork
	pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,  
			parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,  
			parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,  
			parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,  
			parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,  
			parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);

	if (pid == 0) {
		// 子进程处理,即应用进程,当前线程是应用的主线程,即UI线程
		return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
	} else {
		handleParentProc(pid, serverPipeFd);
		return null;
	}
}

3 fork过程

frameworks/base/core/java/com/android/internal/os/Zygote.java

static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,  
		int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,  
		int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,  
		boolean isTopApp, String[] pkgDataInfoList, String[] whitelistedDataInfoList,  
		boolean bindMountAppDataDirs, boolean bindMountAppStorageDirs) {
	ZygoteHooks.preFork();

	int pid = nativeForkAndSpecialize(...);

	ZygoteHooks.postForkCommon();  
	return pid;
}

frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(...) {

	pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore, true); {
		// 调用system call fork
		pid_t pid = fork();
		if (pid == 0) {
			// 子进程的一些处理。比如重新打开所有的fd。
		} else {
		}
	}
  
	if (pid == 0) {
		// 子进程的一些处理。比如设置selinux context, 设置线程名等。并且会调用Zygote的callPostForkChildHooks
		SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,  
				capabilities, capabilities,  
				mount_external, se_info, nice_name, false,  
				is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,  
				is_top_app == JNI_TRUE, pkg_data_info_list,  
				whitelisted_data_info_list,  
				mount_data_dirs == JNI_TRUE,  
				mount_storage_dirs == JNI_TRUE);
	}
	return pid;
}

4 子进程处理

handleChildProc

private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor pipeFd, boolean isZygote) {
	
	Zygote.setAppProcessName(parsedArgs, TAG);
	
	if (parsedArgs.mInvokeWith != null) {  
		// 调用pm,am命令时走到这里
		WrapperInit.execApplication(parsedArgs.mInvokeWith,  
				parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,  
				VMRuntime.getCurrentInstructionSet(),  
				pipeFd, parsedArgs.mRemainingArgs);
	} else {
		if (!isZygote) {
			// 应用进程会走到这里,进入了ZygoteInit类的zygoteInit方法
			return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
					parsedArgs.mDisabledCompatChanges,
					parsedArgs.mRemainingArgs, null /* classLoader */);
		} else {
		    return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
					parsedArgs.mRemainingArgs, null /* classLoader */);
		}
	}
}

zygoteInit

public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,  
		String[] argv, ClassLoader classLoader) {

	// runtime的一些初始化。比如uncaughtExceptionHandler设置,处理应用crash
	RuntimeInit.commonInit();  
	// 进入ART的onZygoteInit,在那里启动第一个binder线程
	ZygoteInit.nativeZygoteInit();
	// 应用初始化。比如设置targetSdk,和最重要的,进入ActivityThread的main方法。
	return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv, classLoader);
}

nativeZygoteInit

这个方法在frameworks/base/core/jni/AndroidRuntime.cpp中

static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)  
{
    gCurRuntime->onZygoteInit();
}

onZygoteInit

frameworks/base/cmds/app_process/app_main.cpp

virtual void onZygoteInit()  
{
    sp<ProcessState> proc = ProcessState::self();
	ALOGV("App process: starting thread pool.\n");
	// 启动第一个binder线程
	proc->startThreadPool();
}

spawnPooledThread

接下来的调用流程如下

startThreadPool
	|--> spawnPooledThread(true)
		|--> sp<Thread> t = new PoolThread(isMain);  
			 t->run(name.string());
				 |--> createThreadEtc
					 |--> androidCreateThreadEtc
						 |--> gCreateThreadFn
							 |--> javaCreateThreadEtc
								 |--> androidCreateRawThreadEtc
									 |--> pthread_create

joinThreadPool

调用pthread_create创建线程, 入口函数是Thread的_threadLoop,接着进入PoolThread的threadLoop
frameworks/native/libs/binder/ProcessState.cpp

virtual bool threadLoop()
{
	// 当前线程加入到binder线程池, mIsMain为true
    IPCThreadState::self()->joinThreadPool(mIsMain);  
	return false;
}

getAndExecuteCommand

frameworks/native/libs/binder/IPCThreadState.cpp

void IPCThreadState::joinThreadPool(bool isMain) {
	// 如果是第一个binder线程,进入looper,否则,注册到looper
	mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
	
	do {
		// 进入循环,不断获取命令并执行
		result = getAndExecuteCommand();
	} while (result != -ECONNREFUSED && result != -EBADF)

	mOut.writeInt32(BC_EXIT_LOOPER);  
	talkWithDriver(false);
}


status_t IPCThreadState::getAndExecuteCommand() {

	// 通过ioctl和binder驱动通信,响应client请求
	result = talkWithDriver();

	if (result >= NO_ERROR) {
		...
		cmd = mIn.readInt32();
		...
		// 执行命令
		result = executeCommand(cmd);
		...
	}
}

status_t IPCThreadState::executeCommand(int32_t cmd) {
	switch ((uint32_t)cmd) {
		case BR_TRANSACTION_SEC_CTX:  
		case BR_TRANSACTION:
		{
			// 函数调用流程

			binder_transaction_data_secctx tr_secctx;
			binder_transaction_data& tr = tr_secctx.transaction_data;
			// 读参数信息
			result = mIn.read(&tr, sizeof(tr));

			// 执行服务端相应的函数
			error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer, &reply, tr.flags);
		}
		break;

		case BR_SPAWN_LOOPER:
			// 当没有空闲的binder线程时,驱动会请求这个命令。服务端新建一个线程并加入binder线程池。
			// 应用进程最多16个,system_server最多32个。
			mProcess->spawnPooledThread(false);  
			break;
	}
}

Conclusion

简单的说,应用线程启动过程如下
1 启动四大组件时,如果应用进程不存在,AMS会请求zygote fork进程。
2 fork完成后,子进程的主线程就是应用的主线程,之后会调用ActivityThread的main方法,进入应用的生命周期。
3 主线程的初始化过程中,会调用到onZygoteInit,新建一个线程,这个线程会加入到binder pool,进入getAndExecuteCommand的循环。
4 当应用没有空闲的binder线程使用,并且binder线程不超过16个时,binder驱动会发送BR_SPAWN_LOOPER给上层的binder线程,然后新建一个线程并加入binder pool。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值