3.3 Binder 线程池启动过程

在3.2.2节中学习了Zygote接收请求并创建应用程序进程,其中有一个遗留的知识点就是,在应用程序进程创建过程中会启动Binder线程池。我们查看ZygoteInit类的zygoteInit方法,如下所示:

在注释1处会在新创建的应用程序进程中创建Binder线程池,下面来查看nativeZygoteInit方法:

很明显nativeZygoteInit是一个JNI方法,它对应的函数是什么呢?在AndroidRuntime.cpp的JNINativeMethod数组中我们得知它对应的函数是com_android_internal_os_ZygoteInit_nativeZygoteInit,如下所示:

接着来查看com_android_internal_os_ZygoteInit_nativeZygoteInit函数:

gCurRuntime是AndroidRuntime类型的指针,它是在AndroidRuntime初始化时就创建的,如下所示:

AppRuntime继承自AndroidRuntime,AppRuntime创建时就会调用AndroidRuntime的构造函数,gCurRuntime就会被初始化,它指向的是AppRuntime,我们来查看AppRuntime的onZygoteInit函数,AppRuntime在app_main.cpp中实现,如下所示:

最后一行会调用ProcessState的startThreadPool函数来启动Binder线程池:

支持Binder通信的进程中都有一个ProcessState类,它里面有一个mThreadPoolStarted变量,用来表示Binder线程池是否已经被启动过,默认值为false。在每次调用startThreadPool函数时都会在注释1处先检查这个标记,从而确保Binder线程池只会被启动一次。如果Binder 线程池未被启动,则在注释2处设置mThreadPoolStarted为true,并调用spawnPooledThread函数来创建线程池中的第一个线程,也就是线程池的主线程,如下所示:

可以看到Binder线程为一个PoolThread。在注释1处调用PoolThread的run函数来启动一个新的线程。下面来查看PoolThread类做了什么:

PoolThread类继承了Thread类。在注释1处调用IPCThreadState的joinThreadPool函数,将当前线程注册到Binder驱动程序中,这样我们创建的线程就加入了Binder线程池中,新创建的应用程序进程就支持Binder进程间通信了,我们只需要创建当前进程的Binder对象,并将它注册到ServiceManager中就可以实现Binder进程间通信,而不必关心进程间是如何通过Binder进行通信的。