Android系统进程间通信(IPC)机制Binder中的Client获(2)

BpMediaPlayerService的构造函数有一个参数impl,它的类型为const sp<IBinder>&,从上面的描述中,这个实际上就是一个BpBinder对象。这样,要创建一个BpMediaPlayerService对象,首先就要有一个BpBinder对象。再来看BpBinder类的构造函数,它有一个参数handle,类型为int32_t,这个参数的意义就是请求MediaPlayerService这个远程接口的进程对MediaPlayerService这个Binder实体的引用了。因此,获取MediaPlayerService这个远程接口的本质问题就变为从Service Manager中获得MediaPlayerService的一个句柄了。

现在,我们就来看一下IMediaDeathNotifier::getMeidaPlayerService的实现:

// establish binder interface to MediaPlayerService    /*static*/const sp<IMediaPlayerService>&   IMediaDeathNotifier::getMediaPlayerService()   {       LOGV("getMediaPlayerService");       Mutex::Autolock _l(sServiceLock);       if (sMediaPlayerService.get() == 0) {           sp<IServiceManager> sm = defaultServiceManager();           sp<IBinder> binder;           do {               binder = sm->getService(String16("media.player"));               if (binder != 0) {                   break;                }                LOGW("Media player service not published, waiting...");                usleep(500000); // 0.5 s            } while(true);              if (sDeathNotifier == NULL) {           sDeathNotifier = new DeathNotifier();       }       binder->linkToDeath(sDeathNotifier);       sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);       }       LOGE_IF(sMediaPlayerService == 0, "no media player service!?");       return sMediaPlayerService;   }  

函数首先通过defaultServiceManager函数来获得Service Manager的远程接口,实际上就是获得BpServiceManager的IServiceManager接口,具体可以参考浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路一文。总的来说,这里的语句:

sp<IServiceManager> sm = defaultServiceManager();  

相当于是:

sp<IServiceManager> sm = new BpServiceManager(new BpBinder(0)); 

这里的0表示Service Manager的远程接口的句柄值是0。

接下去的while循环是通过sm->getService接口来不断尝试获得名称为“media.player”的Service,即MediaPlayerService。为什么要通过这无穷循环来得MediaPlayerService呢?因为这时候MediaPlayerService可能还没有启动起来,所以这里如果发现取回来的binder接口为NULL,就睡眠0.5秒,然后再尝试获取,这是获取Service接口的标准做法。

我们来看一下BpServiceManager::getService的实现:

 

class BpServiceManager : public BpInterface<IServiceManager>   {       ......          virtual sp<IBinder> getService(const String16& name) const       {           unsigned n;           for (n = 0; n < 5; n++){               sp<IBinder> svc = checkService(name);               if (svc != NULL) return svc;               LOGI("Waiting for service %s...\n", String8(name).string());               sleep(1);           }           return NULL;       }          virtual sp<IBinder> checkService( const String16& name) const       {           Parcel data, reply;           data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());           data.writeString16(name);           remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);           return reply.readStrongBinder();       }          ......   };  

    BpServiceManager::getService通过BpServiceManager::checkService执行操作。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwjjgs.html