![Android进阶解密](https://wfqqreader-1252317822.image.myqcloud.com/cover/331/31186331/b_31186331.jpg)
3.3 Binder 线程池启动过程
在3.2.2节中学习了Zygote接收请求并创建应用程序进程,其中有一个遗留的知识点就是,在应用程序进程创建过程中会启动Binder线程池。我们查看ZygoteInit类的zygoteInit方法,如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer812.jpg?sign=1738752816-Z3uWATHkbyiuLuEFyNHkRicpPmWH4MCW-0-8301425cf83ae03f266a976d5cdfd388)
在注释1处会在新创建的应用程序进程中创建Binder线程池,下面来查看nativeZygoteInit方法:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer813.jpg?sign=1738752816-RccrP2EZO0QugkT5aXbJL5I3xhoT1JGJ-0-8f6791a9118b69f130b7770f1e3c3aa1)
很明显nativeZygoteInit是一个JNI方法,它对应的函数是什么呢?在AndroidRuntime.cpp的JNINativeMethod数组中我们得知它对应的函数是com_android_internal_os_ZygoteInit_nativeZygoteInit,如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer814.jpg?sign=1738752816-qNsNB0FTajAoqhGcvPYrXbAnsCGLYKsN-0-ce8dd0342811bf6a0afa6ccace829ad5)
接着来查看com_android_internal_os_ZygoteInit_nativeZygoteInit函数:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer815.jpg?sign=1738752816-PQ3qVmKtkO8Z6eXBrrfuHmOLU1vb1tyn-0-fea1240f81d1e2910cb6fa8c617cf8ca)
gCurRuntime是AndroidRuntime类型的指针,它是在AndroidRuntime初始化时就创建的,如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer816.jpg?sign=1738752816-OqKBerfk7q4iSkndEw5YQzgGmAjO1i05-0-324d2a97e42fbc7bf9fa00cdcd8ebcef)
AppRuntime继承自AndroidRuntime,AppRuntime创建时就会调用AndroidRuntime的构造函数,gCurRuntime就会被初始化,它指向的是AppRuntime,我们来查看AppRuntime的onZygoteInit函数,AppRuntime在app_main.cpp中实现,如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer817.jpg?sign=1738752816-qOl3EAj6E9Wx5Id2oUe1DXOJ3ESYLwKm-0-75cc5d8ce6c9c9572b0cd38776f3eb1b)
最后一行会调用ProcessState的startThreadPool函数来启动Binder线程池:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer818.jpg?sign=1738752816-B4ry20JtMaZY9HSMCg4IXwVUDyKoKMXQ-0-b3e9351ec252ac18c93cb75622538835)
支持Binder通信的进程中都有一个ProcessState类,它里面有一个mThreadPoolStarted变量,用来表示Binder线程池是否已经被启动过,默认值为false。在每次调用startThreadPool函数时都会在注释1处先检查这个标记,从而确保Binder线程池只会被启动一次。如果Binder 线程池未被启动,则在注释2处设置mThreadPoolStarted为true,并调用spawnPooledThread函数来创建线程池中的第一个线程,也就是线程池的主线程,如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer819.jpg?sign=1738752816-fKgosHMlikWmrmGDem94eaFjUTEkTN6M-0-274f9fafd71708db94616053fe1a857d)
可以看到Binder线程为一个PoolThread。在注释1处调用PoolThread的run函数来启动一个新的线程。下面来查看PoolThread类做了什么:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer820.jpg?sign=1738752816-UpT9yJ9MHYa16MWIh6eWSEMN0f1FDzwH-0-9894eb6a5ed2d80b0075fcaa5553e04f)
PoolThread类继承了Thread类。在注释1处调用IPCThreadState的joinThreadPool函数,将当前线程注册到Binder驱动程序中,这样我们创建的线程就加入了Binder线程池中,新创建的应用程序进程就支持Binder进程间通信了,我们只需要创建当前进程的Binder对象,并将它注册到ServiceManager中就可以实现Binder进程间通信,而不必关心进程间是如何通过Binder进行通信的。