以MediaServer为例,进程初始化如下:
1.创建进程中所有Service实例
2.注册service到service manager
3.创建线程池,等待处理binder事件
MediaServer处理原理如下图所示:
上图中,mediaserver的两个线程首先调用binder的ioctl方法并挂起等待binder唤醒,如图中步骤a1和b1所示。其次客户端通过BpXXX发送命令給binder,如步骤a2,b2所示,此时客服端线程将被挂起。binder设备收到请求后首先更新binder_write_read数据结构,然后唤醒挂起的线程,并调用BnXXX::onTransact()执行客户请求。服务端完成处理后将通知binder,binder唤醒客户端线程,从而得到最终结果。
以下为详细调用代码:
frameworks/base/media/mediaserver/Main_mediaserver.cpp
int main(int argc, char** argv)
{
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p", sm.get());
MediaPlayerService::instantiate(); //new MediaPlayerService并注册
CameraService::instantiate();
AudioPolicyService::instantiate();
ProcessState::self()->startThreadPool(); //创建线程并调用IPCThreadState::joinThreadPool(true) why??
IPCThreadState::self()->joinThreadPool(); //在主线程中调用IPCThreadState::joinThreadPool(true)
}
疑点:startThreadPool和joinThreadPool完后有两个线程,主线程和工作线程,而且都在做消息循环,且参数isMain都是true。难道google怕一个线程工作量太多,所以搞两个线程来工作?网上有人测试过把最后一句屏蔽掉,也能正常工作。
frameworks/base/libs/binder/ProcessState.cpp
ProcessState::ProcessState()
: mDriverFD(open_driver())
, mVMStart(MAP_FAILED)
, mManagesContexts(false)
, mBinderContextCheckFunc(NULL)
, mBinderContextUserData(NULL)
, mThreadPoolStarted(false)
, mThreadPoolSeq(1)
{
...}
static int open_driver()
{
if (gSingleProcess) {
return -1;
}
int fd = open("/dev/binder", O_RDWR);
if (fd >= 0) {
fcntl(fd, F_SETFD, FD_CLOEXEC); //这里设置为FD_CLOEXEC表示当程序执行exec函数时本fd将被系统自动关闭,表示不传递给exec创建的新进程 ??
int vers;
status_t result = ioctl(fd, BINDER_V