Binder是Android中使用的进程间通讯机制(IPC)。在Android系统中,应用程序是由Activity、Service、Broadcast Receiver和Content Provider四种类型的组件构成的,它们有可能运行在同一进程中,也有可能运行在不一样的进程中。此外,各类系统组件也运行在独立的进程中。这些运行在不一样进程中的应用程序组件和系统组件之间的通讯机制就是Binder。
Android虽然构建在Linux上面,可是在IPC机制方面,没有利用Linux提供IPC机制,而是使用了一套轻量级的IPC机制—Binder机制。Binder是基于OpenBinder来实现的。OpenBinder最早是由Be Inc.开发的,接着Palm Inc.也跟着使用。Binder是一种进程间通讯机制,它是一种相似于COM和CORBA分布式组件架构,通俗一点,实际上是提供远程过程调用(RPC)功能。android
Binder具备如下特色编程
Binder应用模型
一个IPC通信咱们能够简单理解成Client-Server模式,Client请求Service,Server接收到Client请求后处理相应,或可能带回结果返回给Client。服务器
Binder机制在Android系统的进程间通信模型总结以下:网络
Binder机制的组成多线程
下面以一个简单实例来分析Binder传输。该测试程序由client端调用add()函数,在server端完成加法操做,并返回结果。测试程序的目录结构以下,架构
类图以下所示。左侧为server端,右侧为client端。并发
从Client端的代码看起。Client若是想和Server进行通讯,必须先得到Server的远程接口,这个过程经过Service Manager来实现。Service Manager用来管理Server而且向Client提供查询Server远程接口的功能。分布式
1.---> BinderClientRun.cpp 2. 3.int main(int argc, char** argv) 4.{ 5. int sum = 0; 6. sp<IBinderServiceTest> mBinderServiceTest; 7. 8. if (mBinderServiceTest.get() == 0) { 9. // 经过defaultServiceManager函数来得到Service Manager的远程接口 10. sp<IServiceManager> sm = defaultServiceManager(); 11. sp<IBinder> binder; 12. 13. // 在循环中使用sm->getService不断尝试得到名称为“my.binder.test”的Service,返回binder 14. do { 15. binder = sm->getService(String16("my.binder.test")); 16. if (binder != 0) 17. break; 18. ALOGI("getService fail"); 19. usleep(500000); // 0.5 s 20. } while (true); 21. 22. // 获得Service的binder后,经过interface_cast,将这个binder转化成BpBinderServiceTest 23. mBinderServiceTest = interface_cast<IBinderServiceTest> (binder); 24. ALOGE_IF(mBinderServiceTest == 0, "no IBinderServiceTest!?"); 25. } 26. 27. // BpBinderServiceTest,就能够调用远程server的接口了 28. sum = mBinderServiceTest->add(3, 4); 29. ALOGI("sum = %d", sum); 30. return 0; 31.}
代码中的interface_cast是如何将binder转化为BpBinderServiceTest的呢?Android有意隐藏了这一转换,让应用很轻松的完成这一转换。看一下interface_cast的定义ide
1.---> IInterface.h 2. 3.template<typename INTERFACE> 4.inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) 5.{ 6. return INTERFACE::asInterface(obj); 7.}
interface_cast是一个模板,它返回的是 IBinderServiceTest::asInterface。但在咱们的源码中并无直接实现 asInterface,那它是在哪里实现的呢?让咱们先看一下两个宏定义函数
1.---> IInterface.h 2. 3.#define DECLARE_META_INTERFACE(INTERFACE) \ 4. static const android::String16 descriptor; \ 5. static android::sp<I##INTERFACE> asInterface( \ 6. const android::sp<android::IBinder>& obj); \ 7. virtual const android::String16& getInterfaceDescriptor() const; \ 8. I##INTERFACE(); \ 9. virtual ~I##INTERFACE(); \ 10. 11. 12.#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ 13. const android::String16 I##INTERFACE::descriptor(NAME); \ 14. const android::String16& \ 15. I##INTERFACE::getInterfaceDescriptor() const { \ 16. return I##INTERFACE::descriptor; \ 17. } \ 18. android::sp<I##INTERFACE> I##INTERFACE::asInterface( \ 19. const android::sp<android::IBinder>& obj) \ 20. { \ 21. android::sp<I##INTERFACE> intr; \ 22. if (obj != NULL) { \ 23. intr = static_cast<I##INTERFACE*>( \ 24. obj->queryLocalInterface( \ 25. I##INTERFACE::descriptor).get()); \ 26. if (intr == NULL) { \ 27. intr = new Bp##INTERFACE(obj); \ 28. } \ 29. } \ 30. return intr; \ 31. } \ 32. I##INTERFACE::I##INTERFACE() { } \ 33. I##INTERFACE::~I##INTERFACE() { }
这两个宏会在程序中被使用
1.---> IBinderServiceTest.h 2. 3.class IBinderServiceTest: public IInterface { 4.public: 5. DECLARE_META_INTERFACE(BinderServiceTest); 6. 7. virtual int add(int a, int b) = 0; 8.}; 9. 10. 11.---> IBinderServiceTest.cpp 12. 13.IMPLEMENT_META_INTERFACE(BinderServiceTest, "android.test.IBinderServiceTest");
将这两个宏展开会等到
1.---> IBinderServiceTest.h 2. 3.class IBinderServiceTest: public IInterface { 4.public: 5. static const android::String16 descriptor; 6. static android::sp<IBinderServiceTest > asInterface 7. (const android::sp<android::IBinder>& obj); 8. virtual const android::String16& getInterfaceDescriptor() const; 9. IBinderServiceTest (); 10. virtual ~IBinderServiceTest (); 11. virtual int add(int a, int b) = 0; 12.};
1.---> IBinderServiceTest.cpp 2. 3. const android::String16 IBinderServiceTest ::descriptor("android.test.IBinderServiceTest"); 4. const android::String16& IBinderServiceTest ::getInterfaceDescriptor() const { 5. return IBinderServiceTest ::descriptor; 6. } 7. android::sp<IBinderServiceTest > IBinderServiceTest ::asInterface 8. (const android::sp<android::IBinder>& obj) 9. { 10. android::sp<IBinderServiceTest > intr; 11. if (obj != NULL) { 12. intr = static_cast<IBinderServiceTest *> 13. (obj->queryLocalInterface(IBinderServiceTest ::descriptor).get()); 14. if (intr == NULL) { 15. intr = new BpBinderServiceTest (obj); 16. } 17. } 18. return intr; 19. } 20. IBinderServiceTest ::IBinderServiceTest () { } 21. IBinderServiceTest ::~IBinderServiceTest () { }
展开的宏里,咱们找到了asInterface,这里new了一个 BpBinderServiceTest,而后将其返回。Client端获得Server端的代理BpBinderServiceTest后,就能够像本地调用同样来使用Server端的接口。示例程序中调用了add()函数,看一下它早Proxy中的实现。
1.---> IBinderServiceTest.cpp 2. 3.class BpBinderServiceTest: public BpInterface<IBinderServiceTest> 4.{ 5.public: 6. BpBinderServiceTest(const sp<IBinder>& impl) : 7. BpInterface<IBinderServiceTest> (impl) { 8. } 9. 10. int add(int a, int b) { 11. // Parcel类用来于序列化进程间通讯数据。 12. Parcel data, reply; 13. ALOGI("BpBinderServiceTest add, a = %d, b = %d", a, b); 14. 15. // 写入Binder传输数据的头,这里写入Service描述符“android.test.IBinderServiceTest”。 16. data.writeInterfaceToken(IBinderServiceTest::getInterfaceDescriptor()); 17. // 以后向Binder中写入要发送给Server的数据。 18. data.writeInt32(a); 19. data.writeInt32(b); 20. // 开始进行远端的传输调用。 21. remote()->transact(TEST_ADD, data, &reply); 22. // 读取Server返回的数据。 23. int sum = reply.readInt32(); 24. 25. ALOGI("BpBinderServiceTest sum = %d", sum); 26. return sum; 27. } 28.};
代码中,remote()来自于BpRefBase类,它返回一个BpBinder指针,所以这将调用BpBinder::transact。TEST_ADD是Binder执行的命令编码,Server会根据这个值来执行相应的命令。实际的Binder传输是在IPCThreadState中完成的,传输时同步的,调用返回表示Server端已经执行结束。这里不作详解。
Client端发送命令TEST_ADD,看看Server端是如何执行这个命令的。
1.---> IBinderServiceTest.cpp 2. 3.status_t BnBinderServiceTest::onTransact(uint32_t code, const Parcel& data, 4. Parcel* reply, uint32_t flags) { 5. switch (code) { 6. // 接收到Client端的命令TEST_ADD。 7. case TEST_ADD: { 8. // 检查数据头是否为Service描述符。 9. CHECK_INTERFACE(IBinderServiceTest, data, reply); 10. 11. // 读取输入的数据。 12. int a = data.readInt32(); 13. int b = data.readInt32(); 14. ALOGI("BnBinderServiceTest add, a = %d b = %d", a, b); 15. 16. int sum = 0; 17. // 调用Server对应的函数 18. sum = add(a, b); 19. ALOGI("BnBinderServiceTest sum = %d", sum); 20. // 写入返回数据到Binder。 21. reply->writeInt32(sum); 22. return sum; 23. } 24. default: 25. return BBinder::onTransact(code, data, reply, flags); 26. } 27.}
Server端的源头也是在IPCThreadState中。IPCThreadState借助ProcessState类来与Binder驱动程序交互,接收Client处的请求。以后调用BBinder类的transact函数,并传入相关参数。BBinder类的transact函数最终调用BnBinderServiceTest类的onTransact函数。
下面从Server端启动开始分析。
1.---> BinderServerRun.cpp 2. 3.int main(int argc, char** argv) 4. { 5. // 建立一个ProcessState实例。 6. sp<ProcessState> proc(ProcessState::self()); 7. // 获得Service Manager的远程接口。 8. sp<IServiceManager> sm = defaultServiceManager(); 9. 10. // 增长Service "my.binder.test"到Service Manager中。 11. BinderServiceTest::instantiate(); 12. ProcessState::self()->startThreadPool(); 13. IPCThreadState::self()->joinThreadPool(); 14. return 0; 15.} 16. 17. 18.---> BinderTestServer.cpp 19. 20.void BinderServiceTest::instantiate() { 21. ALOGI("Enter instantiate"); 22. 23. status_t st = defaultServiceManager()->addService( 24. String16("my.binder.test"), new BinderServiceTest()); 25. ALOGD("addService ret=%d", st); 26.} 27. 28.BinderServiceTest::BinderServiceTest() { 29. ALOGD("Constructor"); 30.} 31. 32.BinderServiceTest::~BinderServiceTest() { 33. ALOGD("Destructor"); 34.} 35. 36.int BinderServiceTest::add(int a, int b) { 37. ALOGI("add a = %d, b = %d.", a, b); 38. return a+b; 39.}
Server端首先要经过ProcessState::self()调用建立一个ProcessState实例。ProcessState::self()是ProcessState类的一个静态成员变量,这个函数返回一个全局惟一的ProcessState实例gProcess。代码以下
1.---> ProcessState.cpp 2. 3.sp<ProcessState> ProcessState::self() 4.{ 5. Mutex::Autolock _l(gProcessMutex); 6. if (gProcess != NULL) { 7. return gProcess; 8. } 9. gProcess = new ProcessState; 10. return gProcess; 11.}
ProcessState实例化的过程当中主要完成两个工做。一是会经过open_driver函数打开Binder设备文件/dev/binder,并将打开设备文件描述符保存在成员变量mDriverFD中;二是经过mmap来把设备文件/dev/binder映射到内存中。这里不作详解。
接下来分析startThreadPool()和joinThreadPool()到底作了什么。startThreadPool() 的实现以下面的代码所示:
1.---> ProcessState.cpp 2. 3.void ProcessState::startThreadPool() 4.{ 5. AutoMutex _l(mLock); 6. if (!mThreadPoolStarted) { 7. mThreadPoolStarted = true; 8. spawnPooledThread(true); 9. } 10.} 11....... 12.void ProcessState::spawnPooledThread(bool isMain) 13.{ 14. if (mThreadPoolStarted) { 15. String8 name = makeBinderThreadName(); 16. ALOGV("Spawning new pooled thread, name=%s\n", name.string()); 17. sp<Thread> t = new PoolThread(isMain); 18. t->run(name.string()); 19. } 20.}
PoolThread 是在 IPCThreadState 中定义的一个 Thread 子类,它的实现以下所示:
1.---> ProcessState.cpp 2. 3.class PoolThread : public Thread 4.{ 5.public: 6. PoolThread(bool isMain) 7. : mIsMain(isMain) 8. { 9. } 10. 11.protected: 12. virtual bool threadLoop() 13. { 14. IPCThreadState::self()->joinThreadPool(mIsMain); 15. return false; 16. } 17. 18. const bool mIsMain; 19.};
PoolThread继承Thread类,其run函数调用Thread::run()建立一个线程,最终调用子类的threadLoop函数。threadLoop()也是调用joinThreadPool()完成工做。joinThreadPool()的代码以下。
1.---> IPCThreadState.cpp 2. 3.status_t IPCThreadState::getAndExecuteCommand() 4.{ 5. status_t result; 6. int32_t cmd; 7. 8. result = talkWithDriver(); 9. if (result >= NO_ERROR) { 10. size_t IN = mIn.dataAvail(); 11. if (IN < sizeof(int32_t)) return result; 12. cmd = mIn.readInt32(); 13. IF_LOG_COMMANDS() { 14. alog << "Processing top-level Command: " 15. << getReturnString(cmd) << endl; 16. } 17. 18. result = executeCommand(cmd); 19. 20. // After executing the command, ensure that the thread is returned to the 21. // foreground cgroup before rejoining the pool. The driver takes care of 22. // restoring the priority, but doesn't do anything with cgroups so we 23. // need to take care of that here in userspace. Note that we do make 24. // sure to go in the foreground after executing a transaction, but 25. // there are other callbacks into user code that could have changed 26. // our group so we want to make absolutely sure it is put back. 27. set_sched_policy(mMyThreadId, SP_FOREGROUND); 28. } 29. 30. return result; 31.} 32....... 33.void IPCThreadState::joinThreadPool(bool isMain) 34.{ 35. LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid()); 36. 37. mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); 38. 39. // This thread may have been spawned by a thread that was in the background 40. // scheduling group, so first we will make sure it is in the foreground 41. // one to avoid performing an initial transaction in the background. 42. set_sched_policy(mMyThreadId, SP_FOREGROUND); 43. 44. status_t result; 45. do { 46. processPendingDerefs(); 47. // now get the next command to be processed, waiting if necessary 48. result = getAndExecuteCommand(); 49. 50. if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) { 51. ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting", 52. mProcess->mDriverFD, result); 53. abort(); 54. } 55. 56. // Let this thread exit the thread pool if it is no longer 57. // needed and it is not the main process thread. 58. if(result == TIMED_OUT && !isMain) { 59. break; 60. } 61. } while (result != -ECONNREFUSED && result != -EBADF); 62. 63. LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p\n", 64. (void*)pthread_self(), getpid(), (void*)result); 65. 66. mOut.writeInt32(BC_EXIT_LOOPER); 67. talkWithDriver(false); 68.}
这个函数最终是在一个无穷循环中,经过调用talkWithDriver函数来和Binder驱动程序进行交互,实际上就是调用talkWithDriver来等待Client的请求,而后再调用executeCommand来处理请求,而在executeCommand函数中,最终会调用BBinder::transact来真正处理Client的请求。而BBinder::transact最终会调用onTransact函数来处理,也就实际调用了示例中的BnBinderServiceTest::onTransact。