- Android进阶解密
- 刘望舒
- 603字
- 2020-08-27 17:04:56
3.3 Binder 线程池启动过程
在3.2.2节中学习了Zygote接收请求并创建应用程序进程,其中有一个遗留的知识点就是,在应用程序进程创建过程中会启动Binder线程池。我们查看ZygoteInit类的zygoteInit方法,如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer812.jpg?sign=1739633779-Z5Vbu5MwZBFhvZHFSlmO58tRGIt3iWME-0-0af979227825af932e5f38b43cbe39c6)
在注释1处会在新创建的应用程序进程中创建Binder线程池,下面来查看nativeZygoteInit方法:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer813.jpg?sign=1739633779-l0hN1BUiGMEJuBme7HZ8NmswabJVEqUF-0-a6b1e8122dcfb1d158d7dff9bea8ad8b)
很明显nativeZygoteInit是一个JNI方法,它对应的函数是什么呢?在AndroidRuntime.cpp的JNINativeMethod数组中我们得知它对应的函数是com_android_internal_os_ZygoteInit_nativeZygoteInit,如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer814.jpg?sign=1739633779-dHfksRZheMX19f8h8LIDC8VcVfo4Dk1l-0-33835cddf007fcb263c6109867a987df)
接着来查看com_android_internal_os_ZygoteInit_nativeZygoteInit函数:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer815.jpg?sign=1739633779-bXhdDP789TWIKg3HsC6j2xrNJJOr6kTg-0-a12285993c332cf31b65d2e71e48a6c5)
gCurRuntime是AndroidRuntime类型的指针,它是在AndroidRuntime初始化时就创建的,如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer816.jpg?sign=1739633779-Qt9XT1OoqSxvCxfcRt5WfTdM46iITJzz-0-afbf77dbe5c3c62a288569f955765eb0)
AppRuntime继承自AndroidRuntime,AppRuntime创建时就会调用AndroidRuntime的构造函数,gCurRuntime就会被初始化,它指向的是AppRuntime,我们来查看AppRuntime的onZygoteInit函数,AppRuntime在app_main.cpp中实现,如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer817.jpg?sign=1739633779-c7P0Y7yR5bf5kaOvJxPXqoqE5JDFzixS-0-b64fc41dcb10d5923712c27831c6434b)
最后一行会调用ProcessState的startThreadPool函数来启动Binder线程池:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer818.jpg?sign=1739633779-P69puXCaAerZTxEoNvLQU1aaJOfW6dRU-0-1bb7e1c77c57620e4a8e297ef9e957ea)
支持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=1739633779-nN0eJ2I2mBadw0ZhWlfU41zK1cT9GGl0-0-11bb00f133becf0f3212b3dd4d6575c3)
可以看到Binder线程为一个PoolThread。在注释1处调用PoolThread的run函数来启动一个新的线程。下面来查看PoolThread类做了什么:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer820.jpg?sign=1739633779-MXfDyaPTsqptpXJTUcBtP153y1zHgQ8g-0-635bb178d86e490d642466bc8b2b6b32)
PoolThread类继承了Thread类。在注释1处调用IPCThreadState的joinThreadPool函数,将当前线程注册到Binder驱动程序中,这样我们创建的线程就加入了Binder线程池中,新创建的应用程序进程就支持Binder进程间通信了,我们只需要创建当前进程的Binder对象,并将它注册到ServiceManager中就可以实现Binder进程间通信,而不必关心进程间是如何通过Binder进行通信的。