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线程池。