您的位置:首页 > 其它

Binder机制分析(2)——从MediaService中看Binder的实现和使用(2)

2011-12-27 18:53 435 查看
本文是对《Android技术内幕-系统卷》第三章的摘抄和整理。

1. 如果我们要使用MediaPlayerService服务,那么MediaPlayerService客户端就需要与MediaPlayerService(即BnMediaPlayerService)交互。交互的过程需要建立一个循环,然后读写Binder设备。注意,在BnMediaPlayerService中并没有打开Binder设备和建立一个循环监听,这里实际上是借用ProcessState来完成了MediaPlayerService的一些功能,下面我们继续分析。

前面说过,ProcessState会维护一个进程中的所有服务(Server)代理,每个进程中只能有一个;当然,也包括需要维护这里的MediaPlayerService服务的代理。因此,在main_mediaserver.cpp的main函数中,紧接着由“ProcessState::self()->startThreadPool();”来创建一个线程池并启动,而线程池PoolThread又继承自线程Thread。因此,当PoolThread在执行run函数启动时,会执行Thread的run函数(位于“framework\base\libs\utils\thread.cpp中”),如代码所示。

Thread::run的实现

status_t Thread::run(const char

name, int32_t priority, size_t stack)

{

//省略部分代码

if (mCanCallJava) {

res = createThreadEtc(_threadLoop,

this, name, priority, stack, &mThread);

} else {

res = AndroidCreateRawThreadEtc(_threadLoop,

this, name, priority, stack, &mThread);

}

//省略部分代码

return NO_ERROR;

}

2. 这里通过createThreadEtc创建了一个线程,线程函数为_threadLoop,因此,在_threadLoop函数中又调用了IPCThreadState::self()->joinThreadPool。注意,在main_mediaserver.cpp的main函数中也会调用IPCThreadState::self()->joinThreadPool,也就是说,主线程和工作线程都会执行joinThreadPool;在该函数中通过talkWithDriver函数操作Binder驱动程序,executeCommand函数来执行命令。查看executeCommand的代码可以得知,实际上会根据不同的命令进行不同的解析,但是最终的解析还是调用BBinder::transact函数,而transact又调用了自己的BBinder::onTransact函数。这里的BnMediaPlayerService继承自BBinder,所以会调用到它自己的BnMediaPlayerService::onTransact函数。

3. 最后,如果我们需要使用MediaPlayerService,那么首先就需要创建一个BpMediaPlayer Service,创建过程大致如代码清单3-62所示。

创建BpMediaPlayerService的过程

sp<IServiceManager> sm = defaultServiceManager();

sp<IBinder> binder;

do {

//查询MediaPlayerService,返回Binder

binder = sm->getService(String16("media.player"));

if (binder != 0) {

break;

}

usleep(500000); // 0.5 s

} while(true);

sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);

其过程为:首先通过defaultServiceManager函数获得ServiceManager对象,然后调用Service Manager::getService查询指定名称(media.player)的MediaPlayerService服务,再通过interface_cast将查询得到的Binder转化成BpMediaPlayerService对象。这样,BpMediaPlayerService就可以与BnMediaPlayerService进行通信了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: