Android系统的Binder机制之四——系统Service

转自:http://my.unix-center.net/~Simon_fu/?p=988


        前面我们已经介绍了Android Binder机制的Service ManagerService对象代理1Service对象代理2

        本文将介绍一下Android机制的另外一个重要部分——系统Service。


1、系统Service实例——Media server

      首先我们先看一下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。

2、系统Service的基础——BBinder

      我们仔细查看一下Media Server中定义的四个Service我们将会发现他们都是继承自BBinder,而BBinder又继承自IBinder接口,详细情况请自行查看他们的代码。每个Service都改写了BBinder的onTransact虚函数,当用户发送请求到达Service时,框架将会调用Service的onTransact函数,后面我们将会详细的介绍这个机制。

3、Service注册

     每个Service都需要向“大管家”Service Manager进行注册,调用Service Manager的addService方法注册。这样Service Manager将会运行客户端查询和获取该Service(代理对象),然后客户端就可以通过该Service的代理对象请求该Service的服务。

4、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在IPCThreadState的joinThreadPool方法中,调用talkWithDriver方法和Binder驱动进行交互,读取客户端的请求。当客户端请求到达之后调用executeCommand方法进行处理。

    我们再看一下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方法来响应客户请求。

5、结论

    本文简单介绍了一下系统Service的原理,台湾的高焕堂先生有一篇文章,手把手教怎样实现一个系统Service,你可以在我的博文《(转)高焕堂——Android框架底层结构知多少?》中找到。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值