本文参考《Android系统源代码情景分析》,作者罗升阳
一、测试代码:
~/Android/external/binder/server
----FregServer.cpp
~/Android/external/binder/common
----IFregService.cpp
----IFregService.h
~/Android/external/binder/client
----FregClient.cpp
Binder库(libbinder)代码:
~/Android/frameworks/base/libs/binder
----BpBinder.cpp
----Parcel.cpp
----ProcessState.cpp
----Binder.cpp
----IInterface.cpp
----IPCThreadState.cpp
----IServiceManager.cpp
----Static.cpp
~/Android/frameworks/base/include/binder
----Binder.h
----BpBinder.h
----IInterface.h
----IPCThreadState.h
----IServiceManager.h
----IBinder.h
----Parcel.h
----ProcessState.h
驱动层代码:
~/Android//kernel/goldfish/drivers/staging/android
----binder.c
----binder.h
二、源码分析
继续上一篇Android Binder进程间通信---注册Service组件---发送和处理BC_REPLY返回协议http://blog.csdn.net/jltxgcy/article/details/26339313,执行完waitForResponse函数,参考Android Binder进程间通信---注册Service组件---Client发送BC_TRANSACTION。应该返回IPCThreadState类的transact方法,再返回BpBinder类的transact函数,最后返回BpServiceManager类addService函数。最后再返回FregService类的main函数,实现如下:
~/Android/external/binder/server
----FregServer.cpp
int main(int argc, char** argv) { FregService::instantiate(); ProcessState::self()->startThreadPool();//启动一个Binder线程池 IPCThreadState::self()->joinThreadPool();//主线程加入线程池 return 0; }
首先当前进程的ProcessState对象的成员函数startThreadPool来启动一个Binder线程池,接着继续调用当前线程的IPCThreadState对象的成员函数joinThreadPool,将当前线程加入到前面所启动的Binder线程池中去等待和处理来自Client进程的进程间通信请求。
下面我们就分析ProcessState类的成员函数startThreadPool的实现,在分析过程中,同时也会分析IPCThreadState类的成员函数joinThreadPool的实现。
ProcessState类的成员函数startThreadPool的实现如下:
~/Android/frameworks/base/libs/binder
----ProcessState.cpp
void ProcessState::startThreadPool() { AutoMutex _l(mLock); if (!mThreadPoolStarted) {//默认值为false mThreadPoolStarted = true;//防止它的成员函数spawnPooledThread被重复调用来启动Binder线程池 spawnPooledThread(true); } }
当前进程的ProcessState对象的成员变量mThreadPoolStarted被初始化为false,当它将一个Binder线程池启动起来之后,就会将内部的成员变量mThreadPoolStarted的值设置为true,防止它的成员函数spawnPooledThread被重复调用来启动Binder线程池。spawnPooledThread函数实现如下:
~/Android/frameworks/base/libs/binder
----ProcessState.cpp
void ProcessState::spawnPooledThread(bool isMain) { if (mThreadPoolStarted) { int32_t s = android_atomic_add(1, &mThreadPoolSeq); char buf[32]; sprintf(buf, "Binder Thread #%d", s); LOGV("Spawning new pooled thread, name=%s\n", buf); sp<Thread> t = new PoolThread(isMain);//isMain为true t->run(buf);//启动一个新的线程 } }
创建了一个PoolThread对象t,调用它的成员函数run来启动一个新的线程。
PoolThread类继承了线程类Thread,并且重写了它的线程入口成员函数threadLoop,因此当一个PoolThread对象t所对应的线程启动起来之后,它的成员函数threadLoop就会被调用。实现如下:
~/Android/frameworks/base/libs/binder
----ProcessState.cpp
class PoolThread : public Thread { public: PoolThread(bool isMain) : mIsMain(isMain)//isMain为true { } protected: virtual bool threadLoop() { IPCThreadState::self()->joinThreadPool(mIsMain);//isMain为true return false; } const bool mIsMain; };
和主线程一样调用了IPCThreadState类的成员函数joinThreadPool。实现如下:
~/Android/frameworks/base/libs/binder
----IPCThreadState.cpp
void IPCThreadState::joinThreadPool(bool isMain)//默认值为true { ......... mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);//isMain为true,BC_ENTER_LOOPER ........ status_t result; do { int32_t cmd; ....... result = talkWithDriver();//将自己注册到Binder线程池中,一个无线循环中不断等待进程间通信请求 if (result >= NO_ERROR) { size_t IN = mIn.dataAvail(); if (IN < sizeof(int32_t)) continue; cmd = mIn.readInt32(); ........ result = executeCommand(cmd);//处理进程间通信请求 } ......... if(result == TIMED_OUT && !isMain) {//一直为false,因为isMain为true break; } } while (result != -ECONNREFUSED && result != -EBADF); ........ mOut.writeInt32(BC_EXIT_LOOPER);//退出Binder线程池 talkWithDriver(false); }
参数isMain是一个默认参数,它的默认值为true。从前面的调用过程可以知道,无论是FregServer进程的主线程,还是FregServer进程刚才所创建的线程,它们都是主动(isMain为true)请求加入到Binder线程池的,即它们都不是由于Binder驱动程序请求创建而加入到Binder线程池的。
一个Binder线程的生命周期可以划分为三个阶段:
第一阶段是将自己注册到Binder线程池中;
第二阶段是一个无线循环中不断等待和处理进程间通信请求;
第三阶段是退出Binder线程池。
最后执行完的结果是FregServer有两个线程,睡眠等待进程间通信数据的到来。
Android Binder进程间通信---注册Service组件---启动Binder线程池