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执行操作。