首先,zygote进程在创建之后,才会创建SystemServer进程,而SystemServer进程是由zygote进程fock自身得到的,在fock自身的过程中,首先会结束自身的其他子线程,这样一来除了自身线程以外,其他线程都会被结束然后GC,而Binder是多线程模型,如果使用Binder进行进程间通信的话,则Binder线程也会被结束,而使用Binder进行进程间通信就无法做到。在fork新进程后,启动Zygote的4个Daemon线程,java堆整理,引用队列,以及析构线程。而在zygote通过fock自身创建子进程之后,如果该进程不是zygote进程,则会调用ZygoteInit.zygoteInit方法
private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
...
if (parsedArgs.mInvokeWith != null) {
...
throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
} else {
if (!isZygote) {
// App进程将会调用到这里,执行目标类的main()方法
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
}
}
}
/**
* ZygoteInit.zygoteInit方法
*/
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
RuntimeInit.commonInit(); //初始化运行环境
ZygoteInit.nativeZygoteInit(); //启动Binder线程池
//调用程序入口函数
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
而在zygoteInit方法中,才会对新创建的进程进行运行环境初始化工作以及启动Binder线程池。
其实Binder线程池的启动,是在SystemServer进程创建过程启动的,而在启动SystemServer的过程中,就需要传入ZygoteServer这个Zygote作为Server端的Socket,所以Zygote进程并不能使用Binder进程进行通信,而只能使用Socket。
而且,Binder线程池是在zygote进程启动之后启动的SystemServer进程中启动的,而SystemServer进程是由zygote进程fock自身得到的,所以zygote进程在启动之后,循环等待SystemServer进程的消息的时候,其实还没有Binder线程池。而且fock只支持当前线程的fock,而不支持多线程的fock,但是Binder又是一个多线程模型,在fock的时候会杀死多余的线程,这样一来,binder线程也就会被杀死,这样就没办法使用binder与SystemServer进程进行进程间通信。
fork 的行为是这样的:复制整个用户空间的数据(通常使用 copy-on-write 的策略,所以可以实现的速度很快)以及所有系统对象,然后仅复制当前线程到子进程。这里:所有父进程中别的线程,到了子进程中都是突然蒸发掉的
假设这么一个环境,在 fork 之前,有一个子线程 lock 了某个锁,获得了对锁的所有权。fork 以
后,在子进程中,所有的额外线程都人间蒸发了。而锁却被正常复制了,在子进程看来,这个锁没
有主人,所以没有任何人可以对它解锁。当子进程想 lock 这个锁时,不再有任何手段可以解开
了。程序发生死锁