androidserviceipcbinderbyJim文档格式.docx
- 文档编号:20382436
- 上传时间:2023-01-22
- 格式:DOCX
- 页数:10
- 大小:262.81KB
androidserviceipcbinderbyJim文档格式.docx
《androidserviceipcbinderbyJim文档格式.docx》由会员分享,可在线阅读,更多相关《androidserviceipcbinderbyJim文档格式.docx(10页珍藏版)》请在冰豆网上搜索。
remote()->
transact()
客户端做的:
获得ABC接口,然后调用接口(实际上调用了BpABC,继而通过IPC调用了BnABC,然后调用了具体的功能)
在程序的实现过程中BnABC和BpABC是双继承了接口ABC。
一般来说BpABC是一个实现类,这个实现类不需要在接口中体现,它实际上负责的只是通讯功能,不执行具体的功能;
BnABC则是一个接口类,需要一个真正工作的类来继承、实现它,这个类才是真正执行具体功能的类。
在客户端中,从ISeriviceManager中获得一个ABC的接口,客户端调用这个接口,实际上是在调用BpABC,而BpABC又通过Binder的IPC机制和BnABC通讯,BnABC的实现类在后面执行
2.mediaplayerservice分析IPC通信
2.1servicemanager服务
SericeManager在代码中涉及的两个文件是ISericeManager.h和ISericeManager.cpp。
SericeManager是系统最先被启动的服务,它负责管理后来添加进来的系统服务。
非常值得注意的是:
SericeManager本地功能并没有使现,它实际上由ServiceManager守护进程执行,而用户程序通过调用BpServiceManager来获得ServiceManager的服务。
Android系统Binder机制的总管是ServiceManager,所有的Server(SystemServer)都需要向他注册,应用程序需要向其查询相应的服务。
可见其作用是多么的重要,所以本文首先介绍ServiceManager。
我们看到它先调用binder_open打开binder设备(/dev/binder),其次它调用了binder_become_context_manager函数,这个函数使他自己变为了“Server大总管”,其代码如下:
intmain(intargc,char**argv)
{
structbinder_state*bs;
void*svcmgr=BINDER_SERVICE_MANAGER;
bs=binder_open(128*1024);
if(binder_become_context_manager(bs)){
LOGE("
cannotbecomecontextmanager(%s)\n"
strerror(errno));
return-1;
}
svcmgr_handle=svcmgr;
binder_loop(bs,svcmgr_handler);
return0;
}
intbinder_become_context_manager(structbinder_state*bs)
returnioctl(bs->
fd,BINDER_SET_CONTEXT_MGR,0);
也就是通过ioctl向binder设备声明“我就是server大总管”。
ServiceManager作为一个Server大总管,本身也是一个server。
既然是一个server就要时刻准备为客户端提供服务。
最好ServiceManager调用binder_loop进入到循环状态,并提供了一个回调函数,等待用户的请求。
注意他的ServiceManager的客户端既包括应用程序(查询和获取服务),也包括Server(注册服务)。
ServiceManager的客户怎样才能请求其服务呢?
答案是上文我们提到的情景一样。
客户需要在自己进程中创建一个服务器代理。
现在没有地方去查询服务,那么怎样它的客户怎样生成他的服务代理对象呢?
答案是binder设备(/devbinder)为每一个服务维护一个句柄,调用binder_become_context_manager函数变为“Server大总管”的服务,他的句柄永远是0,是一个“众所周知”的句柄,这样每个程序都可以通过binder机制在自己的进程空间中创建一个ServiceManager代理对象了。
其他的服务在binder设备在设备中的句柄是不定的,需要向“Server大总管”查询才能知道。
2.2mediaplayerservice相关类的关系
在程序的实现过程中BpMediaPlayerService和BnMediaPlayerService是双继承了接口ImediaPlayerService。
BpMediaPlayerService是一个实现类,这个实现类不需要在接口中体现,它实际上负责的只是通讯功能,不执行具体的功能;
BnMediaPlayerService则是一个接口类,需要一个真正工作的类来继承、实现它,这个类为MediaPlayerService,它才是真正执行具体功能的类。
2.3注册mediaplayerservice服务
要使用mediaplayerservice的服务,首先需要把这个服务注册到servicemanager中。
源码文件在:
framework\base\Media\MediaServer\Main_mediaserver.cpp
intmain(intargc,char**argv)
sp<
ProcessState>
proc(ProcessState:
self());
//打开binder驱动
IServiceManager>
sm=defaultServiceManager();
//得到BpserviceManager
LOGI("
ServiceManager:
%p"
sm.get());
AudioFlinger:
instantiate();
MediaPlayerService:
//把MediaPlayerService添加到serviceManager
CameraService:
AudioPolicyService:
ProcessState:
self()->
startThreadPool();
IPCThreadState:
joinThreadPool();
//建立一个线程等到代理端发数据处理
voidMediaPlayerService:
instantiate(){
defaultServiceManager()->
addService(
String16("
media.player"
),newMediaPlayerService());
2.4得到mediaplayerservice服务
得到mediaplayerservice服务需要调用getMediaPlayerService函数。
constsp<
IMediaPlayerService>
&
IMediaDeathNotifier:
getMediaPlayerService()
LOGV("
getMediaPlayerService"
);
Mutex:
Autolock_l(sServiceLock);
if(sMediaPlayerService.get()==0){
IBinder>
binder;
do{
binder=sm->
getService(String16("
));
if(binder!
=0){
break;
LOGW("
Mediaplayerservicenotpublished,waiting..."
usleep(500000);
//0.5s
}while(true);
if(sDeathNotifier==NULL){
sDeathNotifier=newDeathNotifier();
binder->
linkToDeath(sDeathNotifier);
sMediaPlayerService=interface_cast<
(binder);
LOGE_IF(sMediaPlayerService==0,"
nomediaplayerservice!
?
"
returnsMediaPlayerService;
通过getService我们得到的是这个服务对应的binder?
(怎么得到?
),然后通过interface_cast<
把这个binder转换成对应的BpMediaPlayerService。
怎么转换的呢?
template<
typenameINTERFACE>
//模板类
inlinesp<
INTERFACE>
interface_cast(constsp<
obj)
returnINTERFACE:
asInterface(obj);
用ImediaPlayerService替换INTERFACE为:
IMediaPlayerService>
returnIMediaPlayerService:
在代码
classIMediaPlayerService:
publicIInterface
public:
DECLARE_META_INTERFACE(MediaPlayerService);
…
#defineDECLARE_META_INTERFACE(INTERFACE)\
staticconstandroid:
String16descriptor;
\
staticandroid:
sp<
I##INTERFACE>
asInterface(\
constandroid:
android:
obj);
virtualconstandroid:
String16&
getInterfaceDescriptor()const;
I##INTERFACE();
virtual~I##INTERFACE();
#defineIMPLEMENT_META_INTERFACE(INTERFACE,NAME)\
String16I##INTERFACE:
descriptor(NAME);
I##INTERFACE:
getInterfaceDescriptor()const{\
returnI##INTERFACE:
descriptor;
}\
android:
asInterface(\
obj)\
{\
intr;
if(obj!
=NULL){\
intr=static_cast<
I##INTERFACE*>
(\
obj->
queryLocalInterface(\
descriptor).get());
if(intr==NULL){\
intr=newBp##INTERFACE(obj);
returnintr;
I##INTERFACE(){}\
I##INTERFACE:
~I##INTERFACE(){}\
用MediaPlayerService替换完INTERFACE后变为:
#defineDECLARE_META_INTERFACE(MediaPlayerService)\
IMediaPlayerService>
IMediaPlayerService();
virtual~IMediaPlayerService();
#defineIMPLEMENT_META_INTERFACE(MediaPlayerService,NAME)\
String16IMediaPlayerService:
IMediaPlayerService:
returnIMediaPlayerService:
IMediaPlayerService*>
intr=newBpMediaPlayerService(obj);
在BpMediaPlayerService的构造函数中
classBpMediaPlayerService:
publicBpInterface<
BpMediaPlayerService(constsp<
impl)
:
BpInterface<
(impl)
{
下面通过调用BpMediaPlayerService中的函数来和BINDER通信来实现调用真正服务的目的。
下面分析如何通过getService我们得到的是这个服务对应的binder!
在服务端处理情况
客户端得到的结果:
Parcel:
readStrongBinder()const
val;
unflatten_binder(ProcessState:
self(),*this,&
val);
returnval;
在客户端得到服务的代理后,我们就可以通过调用代理的函数,来实现调用远端服务的目的。
但是这其中走了很长。
3.实现自己服务的IPC通信
首先定义一个接口类IXXX,然后定义本地服务BnXXX实现onTransact函数。
实现XXX类实现所有接口类IXXX定义的接口;
实现BpXXX类实现所有接口类IXXX定义的接口(本质是通过binder传给)BnXXX,进而让XXX来处理。
IXXX:
定义接口。
BnXXX:
onTransact()
BpXXX:
//把binder转换成BpXXX。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- androidserviceipcbinderbyJim