Service组件是在Server进程中运行的。Service进程在启动时, 会首先将它里面的Service组件注册到ServiceManager中, 接着再启动一个Binder线程池来等待和处理Client进程的通信请求。
1、 注册Service组件
要注册一个Service组件,首先调用Binder库提供的函数defaultServiceManager来获得一个ServiceManager代理对象, 然后再调用它的成员函数addService将该Service组件FregService注册到ServiceManager中。
函数defaultServiceManager返回的ServiceManager代理对象的类型为BpServiceManager
代码路径:/frameworks/native/libs/binder/IServiceManager.cpp
(http://androidxref.com/8.0.0_r4/xref/frameworks/native/libs/binder/IServiceManager.cpp)
34sp<IServiceManager> defaultServiceManager()
35{
36 if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
37
38 {
39 AutoMutex _l(gDefaultServiceManagerLock);
40 while (gDefaultServiceManager == NULL) {
41 gDefaultServiceManager = interface_cast<IServiceManager>(
42 ProcessState::self()->getContextObject(NULL));
43 if (gDefaultServiceManager == NULL)
44 sleep(1);
45 }
46 }
47
48 return gDefaultServiceManager;
49}
调用BpServiceManager类的成员函数addService来注册Service组件
代码路径:/frameworks/native/libs/binder/IServiceManager.cpp
(http://androidxref.com/8.0.0_r4/xref/frameworks/native/libs/binder/IServiceManager.cpp)
163 virtual status_t addService(const String16& name, const sp<IBinder>& service,
164 bool allowIsolated)
165 {
166 Parcel data, reply;
167 data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
168 data.writeString16(name);
169 data.writeStrongBinder(service);
170 data.writeInt32(allowIsolated ? 1 : 0);
171 status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
172 return err == NO_ERROR ? reply.readExceptionCode() : err;
173 }
Client进程和Server进程的一次进程间通信过程可以划分为如下五个 步骤。
1、Client进程将进程间通信数据封装成 一个Parcel对象 ,以便可以将进程间通信数据传递给Binder驱动程序。
2、Client进程向Binder驱动程序发送一个BC_TRANSACTION命令协议。Binder驱动程序根据协议内容找到目标Server进程之后,就会向Client进程发送一个BR_TRANSACTION_COMPLETE返回协议,表示它的进程间通信请求已经被接。Client进程接收到Binder驱动程序发送给它的BR_TRANSACTION_COMPLETE 返回协议,并且对它进行处理之后,就会再次进入到Binder驱动程序中去等待目标Server进程返回进程间通信结果。
3、Binder驱动程序在向Client进程发送BR_TRANSACTION_COMPLETE返回协议的同时,也会向目标Server进程发送一个BR_TRANSACTION返回协议,请求目标Server进程处理该进程间通信请求。
4、Server进程接收到Binder驱动程序发来的BR_TRANSACTION返回协议,并且对它进行处理之后,就会向Binder驱动程序发送一个BC_REPLY命令协议。Binder驱动程序根据协议内容找到目标Client进程之后,就会向Server进程发送一个BR_TRANSACTION_COMPLETE返回协议,表示它返回的进程间通信结果已经收到了。Server进程接收到Binder驱动程序发送给它的BR_TRANSACTION_COMPLETE返回协议,并且对它进行处理之后,一次进程间通信过程就结束了。接着它会再次进入到 Binder驱动程序中去等待下一次进程间通信请求。
5、Binder驱动程序向Server进程发送BR_TRANSACTION_COMPLETE返回协议的同时,也会向目标Client进程发送一个BR_REPLY返回协议,表示Server进程已经处理完成它的进程间通信请求了, 并且将进程间通信结果返回给它
2 、启动Binder线程池
一个进程是通过调用其内部的ProcessState对象的成员函数startThreadPool来启动一个Binder线程池的。
调用当前进程的ProcessState对象的成员函数startThreadPool来启动一个Binder线程池, 接着继续调用当前线程的IPCThreadState对象的成员函数joinThreadPool,将当前线程加入到前面所启动的Binder线程池中去等待和处理来自Client进程的进程间通信请求。
代码路径:/frameworks/native/libs/binder/ProcessState.cpp
(http://androidxref.com/8.0.0_r4/xref/frameworks/native/libs/binder/ProcessState.cpp)
145void ProcessState::startThreadPool()
146{
147 AutoMutex _l(mLock);
148 if (!mThreadPoolStarted) {
149 mThreadPoolStarted = true;
150 spawnPooledThread(true);
151 }
152}
当前进程的ProcessState对象的成员变量mThreadPoolStarted被初始化为false, 当它将一个Binder线程池启动起来之后, 就会将内部的成员变量mThreadPoolStarted的值设置为true, 防止它的成员函数spawnPooledThread被重复调用来启动Binder线程池。
代码路径:/frameworks/native/libs/binder/ProcessState.cpp
(http://androidxref.com/8.0.0_r4/xref/frameworks/native/libs/binder/ProcessState.cpp)
300void ProcessState::spawnPooledThread(bool isMain)
301{
302 if (mThreadPoolStarted) {
303 String8 name = makeBinderThreadName();
304 ALOGV("Spawning new pooled thread, name=%s\n", name.string());
305 sp<Thread> t = new PoolThread(isMain);
306 t->run(name.string());
307 }
308}
在306行调用它的成员函数run来启动一个新的线程
Pool Thread类继承了线程类Thread,并且重写了它的线程人口成员函数threadLoop,因此,当一个PoolThread对象t所对应的线程启动起来之后, 它的成员函数threadLoop就会被调用。
代码路径:/frameworks/native/libs/binder/ProcessState.cpp
(http://androidxref.com/8.0.0_r4/xref/frameworks/native/libs/binder/ProcessState.cpp)
58protected:
59 virtual bool threadLoop()
60 {
61 IPCThreadState::self()->joinThreadPool(mIsMain);
62 return false;
63 }
64
65 const bool mIsMain;
66};
代码路径:/frameworks/native/libs/binder/IPCThreadState.cpp
(http://androidxref.com/8.0.0_r4/xref/frameworks/native/libs/binder/IPCThreadState.cpp)
493void IPCThreadState::joinThreadPool(bool isMain)
494{
495 LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
496
497 mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
498
499 status_t result;
500 do {
501 processPendingDerefs();
502 // now get the next command to be processed, waiting if necessary
503 result = getAndExecuteCommand();
504
505 if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
506 ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
507 mProcess->mDriverFD, result);
508 abort();
509 }
510
511 // Let this thread exit the thread pool if it is no longer
512 // needed and it is not the main process thread.
513 if(result == TIMED_OUT && !isMain) {
514 break;
515 }
516 } while (result != -ECONNREFUSED && result != -EBADF);
517
518 LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%d\n",
519 (void*)pthread_self(), getpid(), result);
520
521 mOut.writeInt32(BC_EXIT_LOOPER);//向Binder驱动程序发送一个BC_EXIT_LOOPER命令协议,通知Binder驱动程序退出Binder线程池
522 talkWithDriver(false);
523}
参数isMain是一个默认参数,它的默认值为true。
一个Binder线程的生命周期可以划分为三个阶段:第一阶段是将自己注册到Binder线程池中;第二个阶段是在一个无限循环中不断地等待和处理进程间通信请求;第三个阶段是退出Binder线程池。