本文系作者自己学习之所用,文章内容仅出自作者拙劣之思考,问题之处烦请不吝指教。
在frameworks\av\media\libmedia\mediaplayer.cpp中会有语句:const sp<IMediaPlayerService>& service(getMediaPlayerService()); 来建立MediaPlayerService的binder接口,那么这个getMediaPlayerService()是如何工作的呢,这篇文章简单看一下。
本文涉及到的源文件:
frameworks/av/include/media/mediaplayer.h
frameworks/av/media/libmedia/mediaplayer.cpp
frameworks/av/include/media/IMediaDeathNotifier.h
frameworksav/media/libmedia/IMediaDeathNotifier.cpp
首先我们要明确的是,getMediaPlayerService() 是IMediaDeathNotifier类的公有静态成员函数,而MediaPlayer继承自IMediaDeathNotifier,所以可以直接引用。
getMediaPlayerService() 在IMediaDeathNotifier类中的声明:
1 class IMediaDeathNotifier: virtual public RefBase
2 {
3 :
4 ......
5 static const sp<IMediaPlayerService>& getMediaPlayerService(); // 静态、公有
6 7 };
MediaPlayer继承自IMediaDeathNotifier:
class MediaPlayer : BnMediaPlayerClient,2 public virtual IMediaDeathNotifier // 注意继承关系
.......
5 }
重点看一下getMediaPlayerService()方法的定义:
1 // establish binder interface to MediaPlayerService
2 /*static*/const sp<IMediaPlayerService>&
3 IMediaDeathNotifier::getMediaPlayerService()
4 5 ALOGV("getMediaPlayerService");
6 Mutex::Autolock _l(sServiceLock);
7 if (sMediaPlayerService == 0) {
8 sp<IServiceManager> sm = defaultServiceManager(); 首先得到ServiceManager的引用
9 sp<IBinder> binder;
10 do {
11 binder = sm->getService(String16(media.player")); 向ServiceManager申请服务
12 if (binder != 13 break;
14 }
15 ALOGW(Media player service not published,waiting...16 usleep(500000); 0.5 s
17 } while (true18
19 if (sDeathNotifier == NULL) {
20 sDeathNotifier = new DeathNotifier();
21 }
22 binder->linkToDeath(sDeathNotifier);
23 sMediaPlayerService = interface_cast<IMediaPlayerService>(binder); 类型转换为IMediaPlayerService
24 }
25 ALOGE_IF(sMediaPlayerService == 0,no media player service!?26 return sMediaPlayerService;
27 }
上面这段代码的函数实现就是典型的通过ServiceManager获取binder服务的过程。
顺便提一下,MediaPlayerService的注册是在 mediaserver (frameworks/av/media/mediaserver/main_mediaserver.cpp)中完成的
int main(int argc __unused,char** argv)
MediaPlayerService::instantiate();
5 6 }
MediaPlayerService的instantiate函数:
void MediaPlayerService::instantiate() { 2 defaultServiceManager()->addService( 3 String16("),1)"> MediaPlayerService()); 4 }