6.4.2 子承父业

根据前面的分析可知,MediaPlayerService驻留在MediaServer进程中,这个进程有两个线程在talkWithDriver。假设其中有一个线程收到了请求信息,它最终会通过executeCommand调用来处理这个请求,实现代码如下所示:


[—>IPCThreadState.cpp]

status_t IPCThreadState:executeCommand(int32_t cmd)

{

BBinder*obj;

RefBase:weakref_type*refs;

status_t result=NO_ERROR;

switch(cmd){

case BR_ERROR:

result=mIn.readInt32();

break;

……

case BR_TRANSACTION:

{

binder_transaction_data tr;

result=mIn.read(&tr,sizeof(tr));

if(result!=NO_ERROR)break;

Parcel buffer;

Parcel reply;

if(tr.target.ptr){

/*

看到BBinder想起图6-3了吗?BnServiceXXX从BBinder派生,

这里的b实际就是实现BnServiceXXX的那个对象,这样就直接定位到了业务层的对象。

*/

sp<BBinder>b((BBinder*)tr.cookie);

const status_t error=b->transact(tr.code,buffer,&reply,0);

if(error<NO_ERROR)reply.setError(error);

}else{

/*

the_context_object是IPCThreadState.cpp中定义的一个全局变量。可通过setTheContextObject函数设置。

*/

const status_t error=

the_context_object->transact(tr.code,buffer,&reply,0);

if(error<NO_ERROR)reply.setError(error);

}

break;

……


BBinder和业务层有什么关系?还记得图6-3吗?我们以MediaPlayerService为例,来梳理一下其派生关系,如图6-5所示:

6.4.2 子承父业 - 图1

图 6-5 MediaPlayerService家谱

BnMediaPlayerService实现了onTransact函数,它将根据消息码调用对应的业务逻辑函数,这些业务逻辑函数由MediaPlayerService来实现。这一路的历程,如下面的代码所示:


[—>Binder.cpp]

status_t BBinder:transact(

uint32_t code,const Parcel&data,Parcel*reply,uint32_t flags)

{

data.setDataPosition(0);

status_t err=NO_ERROR;

switch(code){

case PING_TRANSACTION:

reply->writeInt32(pingBinder());

break;

default:

//调用子类的onTransact,这是一个虚函数。

err=onTransact(code,data,reply,flags);

break;

}

if(reply!=NULL){

reply->setDataPosition(0);

}

return err;

}

[—>IMediaPlayerService.cpp]

status_t BnMediaPlayerService:onTransact(uint32_t code,const Parcel&data,

Parcel*reply,uint32_t flags)

{

switch(code){

……

case CREATE_MEDIA_RECORDER:{

CHECK_INTERFACE(IMediaPlayerService,data,reply);

//从请求数据中解析对应的参数。

pid_t pid=data.readInt32();

//子类要实现createMediaRecorder函数。

sp<IMediaRecorder>recorder=createMediaRecorder(pid);

reply->writeStrongBinder(recorder->asBinder());

return NO_ERROR;

}break;

case CREATE_METADATA_RETRIEVER:{

CHECK_INTERFACE(IMediaPlayerService,data,reply);

pid_t pid=data.readInt32();

//子类要实现createMetadataRetriever函数。

sp<IMediaMetadataRetriever>retriever=createMetadataRetriever(pid);

reply->writeStrongBinder(retriever->asBinder());

return NO_ERROR;

}break;

default:

return BBinder:onTransact(code,data,reply,flags);

}

}


通过上面的分析,我们是否能更清晰地理解了图6-3、图6-4和图6-5所表达的意义了呢?