转自:http://my.unix-center.net/~Simon_fu/?p=988
前面我们已经介绍了Android Binder机制的Service Manager,Service对象代理1,Service对象代理2。
本文将介绍一下Android机制的另外一个重要部分——系统Service。
首先我们先看一下Android一个实例Media Service,代码位于framework/base/media/mediaserver/main_mediaserver.cpp文件:
1: // System headers required for setgroups, etc. 2: #include <sys/types.h> 3: #include <unistd.h> 4: #include <grp.h> 5: 6: #include <binder/IPCThreadState.h> 7: #include <binder/ProcessState.h> 8: #include <binder/IServiceManager.h> 9: #include <utils/Log.h> 10: 11: #include <AudioFlinger.h> 12: #include <CameraService.h> 13: #include <MediaPlayerService.h> 14: #include <AudioPolicyService.h> 15: #include <private/android_filesystem_config.h> 16: 17: using namespace android; 18: 19: int main(int argc, char** argv) 20: { 21: sp<ProcessState> proc(ProcessState::self()); 22: sp<IServiceManager> sm = defaultServiceManager(); 23: LOGI("ServiceManager: %p", sm.get()); 24: AudioFlinger::instantiate(); 25: MediaPlayerService::instantiate(); 26: CameraService::instantiate(); 27: AudioPolicyService::instantiate(); 28: ProcessState::self()->startThreadPool(); 29: IPCThreadState::self()->joinThreadPool(); 30: }
我们发现Media Server是一个进程,并且该程序的实现表面上也挺简单,其实并不简单,让我们慢慢分析一下Media Server。
1、第一句创建创建一个ProcessState的引用,但是这个对象后面并没有被调用到,那么为什么创建呢?请回想一下我在博文《Android系统的Binder机制之二——服务代理对象(1)》中介绍ProcessState对象时提到:如果一个进程要使用Binder机制,那么他的进程中必须要创建一个ProcessState对象来负责管理Service的代理对象。
2、第二句调用defaultServiceManager获得一个Service Manager代理对象,我在《Android系统的Binder机制之二——服务代理对象(1)》已经对此有了详细的介绍这里就不赘述了。
3、后面几行都是创建具体的Service,我们展开之后发现都是一些调用Service Manager的addService进行注册的函数,以AudioFlinger为例,instantiate代码如下:
1: void AudioFlinger::instantiate() { 2: defaultServiceManager()->addService( 3: String16("media.audio_flinger"), new AudioFlinger()); 4: }
4、最后调用ProcessState的startThreadPool方法和IPCThreadState的joinThreadPool使Media Server进入等待请求的循环当中。
我们可以看出一个进程中可以有多个Service,Media Server这个进程中就存AudioFlinger, MediaPlayerService , CameraService ,AudioPolicyService四个Service。
我们仔细查看一下Media Server中定义的四个Service我们将会发现他们都是继承自BBinder,而BBinder又继承自IBinder接口,详细情况请自行查看他们的代码。每个Service都改写了BBinder的onTransact虚函数,当用户发送请求到达Service时,框架将会调用Service的onTransact函数,后面我们将会详细的介绍这个机制。
每个Service都需要向“大管家”Service Manager进行注册,调用Service Manager的addService方法注册。这样Service Manager将会运行客户端查询和获取该Service(代理对象),然后客户端就可以通过该Service的代理对象请求该Service的服务。
每个Service必须要进入死循环,等待客户端请求的到达,本例中最后两句就是使Service进行等待请求的循环之中。ProcessState的startThreadPool方法最终调用的也是IPCThreadState的joinThreadPool方法,具体请查看代码。IPCThreadState的joinThreadPool方法的代码如下:
1: void IPCThreadState::joinThreadPool(bool isMain) 2: { 3: ...... 4: do { 5: int32_t cmd; 6: 7: ...... 8: 9: // now get the next command to be processed, waiting if necessary 10: result = talkWithDriver(); 11: if (result >= NO_ERROR) { 12: ...... 13: 14: result = executeCommand(cmd); 15: } 16: 17: ...... 18: } while (result != -ECONNREFUSED && result != -EBADF); 19: 20: ...... 21: }
我们再看一下Service怎样处理客户端的请求?我们们查看一下executeCommand方法的源码:
1: status_t IPCThreadState::executeCommand(int32_t cmd) 2: { 3: BBinder* obj; 4: RefBase::weakref_type* refs; 5: status_t result = NO_ERROR; 6: 7: switch (cmd) { 8: ...... 9: case BR_TRANSACTION: 10: { 11: ...... 12: if (tr.target.ptr) { 13: sp<BBinder> b((BBinder*)tr.cookie); 14: const status_t error = b->transact(tr.code, buffer, &reply, 0); 15: if (error < NO_ERROR) reply.setError(error); 16: 17: } 18: ...... 19: } 20: break; 21: 22: ...... 23: } 24: 25: if (result != NO_ERROR) { 26: mLastError = result; 27: } 28: 29: return result; 30: }
可以看到IPCThreadState将会直接调用BBinder的transact方法来处理客户端请求,我们再看一下BBinder的transact方法:
1: status_t BBinder::transact( 2: uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 3: { 4: data.setDataPosition(0); 5: 6: status_t err = NO_ERROR; 7: switch (code) { 8: case PING_TRANSACTION: 9: reply->writeInt32(pingBinder()); 10: break; 11: default: 12: err = onTransact(code, data, reply, flags); 13: break; 14: } 15: 16: if (reply != NULL) { 17: reply->setDataPosition(0); 18: } 19: 20: return err; 21: }
我们发现他将会叫用自己的虚函数onTransact。我们前面提到所有的Service都集成自BBinder,并且都改写了onTransact虚函数。那么IPCThreadState将会调用Service定义onTransact方法来响应客户请求。
本文简单介绍了一下系统Service的原理,台湾的高焕堂先生有一篇文章,手把手教怎样实现一个系统Service,你可以在我的博文《(转)高焕堂——Android框架底层结构知多少?》中找到。