图解AndroidBinder 和 Service.docx

上传人:b****9 文档编号:23319991 上传时间:2023-05-16 格式:DOCX 页数:39 大小:820.31KB
下载 相关 举报
图解AndroidBinder 和 Service.docx_第1页
第1页 / 共39页
图解AndroidBinder 和 Service.docx_第2页
第2页 / 共39页
图解AndroidBinder 和 Service.docx_第3页
第3页 / 共39页
图解AndroidBinder 和 Service.docx_第4页
第4页 / 共39页
图解AndroidBinder 和 Service.docx_第5页
第5页 / 共39页
点击查看更多>>
下载资源
资源描述

图解AndroidBinder 和 Service.docx

《图解AndroidBinder 和 Service.docx》由会员分享,可在线阅读,更多相关《图解AndroidBinder 和 Service.docx(39页珍藏版)》请在冰豆网上搜索。

图解AndroidBinder 和 Service.docx

图解AndroidBinder和Service

在Zygote启动过程 一文中我们说道,Zygote一生中最重要的一件事就是生下了SystemServer这个大儿子,SystemServer担负着提供系统Service的重任,在深入了解这些Service之前,我们首先要了解什么是Service?

它的工作原理是什么?

 

 1.Service是什么?

 简单来说,Service就是提供服务的代码,这些代码最终体现为一个个的接口函数,所以,Service就是实现一组函数的对象,通常也称为组件。

Android的Service有以下一些特点:

 1. 请求Service服务的代码(Client) 和Service本身(Server)不在一个线程,很多情况下不在一个进程内。

跨进程的服务称为远端(Remote)服务,跨进程的调用称为IPC。

通常应用程序通过代理(Proxy)对象来访问远端的Service。

 2. Service可以运行在native端(C/C++),也可以运行在Java端。

同样,Proxy可以从native端访问JavaService,也可以从Java端访问nativeservice,也就是说,service的访问与语言无关。

 3. Android里大部分的跨进程的IPC都是基于Binder实现。

 4. Proxy通过Interface类定义的接口访问Server端代码。

 5. Service可以分为匿名和具名Service.前者没有注册到ServiceManager,应用无法通过名字获取到访问该服务的Proxy对象。

 所以,要了解Service,我们得先从Binder入手。

 2. Binder

   

   先给一张Binder相关的类图一瞰Binder全貌,从上面的类图(点击看大图)跟Binder大致有这么几部分:

          Native实现:

 IBinder, BBinder,BpBinder,IPCThread,ProcessState,IInterface,etc

          Java实现:

 IBinder,Binder,BinderProxy,Stub,Proxy.

          BinderDriver:

binder_proc,binder_thread,binder_node,etc.

   我们将分别对这三部分进行详细的分析,首先从中间的Native实现开始。

   通常来说,接口是分析代码的入口,Android中'I'打头的类统统是接口类(C++里就是抽象类),自然,分析Binder就得先从IBinder下手。

先看看他的定义。

          

classIBinder:

publicvirtualRefBase

{

public:

virtualspqueryLocalInterface(constString16&descriptor);//返回一个IInterface对象

...

virtualconstString16&getInterfaceDescriptor()const=0;

virtualboolisBinderAlive()const=0;

virtualstatus_tpingBinder()=0;

virtualstatus_tdump(intfd,constVector&args)=0;

virtualstatus_ttransact(uint32_tcode,

constParcel&data,

Parcel*reply,

uint32_tflags=0)=0;

virtualstatus_tlinkToDeath(constsp&recipient,

void*cookie=NULL,

uint32_tflags=0)=0;

virtualstatus_tunlinkToDeath(constwp&recipient,

void*cookie=NULL,

uint32_tflags=0,

wp*outRecipient=NULL)=0;

...

virtualBBinder*localBinder();//返回一个BBinder对象

virtualBpBinder*remoteBinder();//返回一个BpBinder对象

};

   有接口必然有实现,从图中可以看出,BBinder和BpBinder都是IBinder的实现类,它们干啥用的,有啥区别?

有兴趣同学可以去分别去读读他们的代码,分别在

∙ Bpinder:

frameworks/native/lib/binder/BpBinder.cpp

∙ BBinder:

frameworks/native/lib/binder/Binder.cpp

   这里我们简单总结一下他们的区别:

接口

BBinder

BpBinder

queryLocalInterface()

没有实现,默认实现IBinder默认{reutrnNULL};  

没有实现IBinder默认实现{returnNULL}

getInterfaceDescriptor()  

{returnsEmptyDescriptor;}  

   (this)->transact(INTERFACE_TRANSACTION,send,&reply);

    ...

   mDescriptorCache=res;  

isBinderAlive()  

{returntrue;}

{returnmAlive!

=0;}

pingBinder()

{returnNoError;}

{transact(PING_TRANSACTION,send,&reply);

linkToDeath()

{returnINVALID_OPERATION;}  

{self->requestDeathNotification(mHandle,this);}

unlinkToDeath()  

{returnINVALID_OPERATION;}

{self->clearDeathNotification(mHandle,this);}

localBinder()

{returnthis;}

没有实现,IBinder默认实现{returnNULL};

remoteBinder()

没有实现,IBinder默认实现{returnNULL;}

{returnthis};

transact()

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

IPCThreadState:

:

self()->transact(mHandle,code,data,reply,flags);

onTransact()

   switch(code){

       caseINTERFACE_TRANSACTION:

           reply->writeString16(getInterfaceDescriptor());

           returnNO_ERROR;       ...

没有实现

 

 

 

   

 

 

 

 

 

 

 

     

 

 

看出来了吧,它们的差异在于它们是通信两端的不同实现,BBinder是服务端,而BpBinder是客户端,为什么这么说?

1. pingBinder,BBinder直接返回OK,而BpBinder需要运行一个transact函数,这个函数具体做什么,我们后面会介绍。

2. linkToDeath()是用来在服务挂的时候通知客户端的,那服务端当然不需要自己监视自己咯,所以BBinder直接返回非法,而Bpbinder需要通过requestDeathNotification()要求某人完成这个事情,究竟是谁提供这个服务?

答案后面揭晓。

3. 在Android中,remote一般代表某个远端对象的本地代理,想象一下航空公司和机票代理,BBinder是航空公司,当然没有remote的了,那BpBinder就是机票代理了,所以remote()自然返回自己了。

4. Transact的英文意思是交易,就是买卖嘛,那自然transact()就是买的操作,而onTransact()就是卖的操作,BBinder的transact()的实现就是onTransact(),航空公司的买票当然不用通过机票代理了,直接找自己人就好了。

所以结论是,BBinder代表着服务端,而BpBinder则是它在客户端的代理,客户程序通过BpBinder的transact()发起请求,而服务器端的BBinder在onTranscat()里响应请求,并将结果返回。

可是交易肯定有目标的吧,回到航空公司和机票代理的例子,如果要订去某个地方的机票,我们怎么也得先查询一下都有那些航班,然后才能告诉机票代理订具体的航班号吧。

这里的查询和预订可以看成服务的接口函数,而航班号就是我们传递给机票代理的参数。

客户程序通过queryLocalInterface()可以知道航空公司都提供哪些服务。

可是奇怪的是BBinder和BpBinder都没有实现这个接口啊,那肯定另有他人实现这个类了,这个人就是IInterface.h,看看代码

template

inlinespBnInterface:

:

queryLocalInterface(

constString16&_descriptor)

{

if(_descriptor==INTERFACE:

:

descriptor)returnthis;

returnNULL;

}

 

BnInterface对象将自己强制转换成IInterface对象返回,看看BnInterface的定义:

template

classBnInterface:

publicINTERFACE,publicBBinder

{

public:

virtualspqueryLocalInterface(constString16&_descriptor);

virtualconstString16&getInterfaceDescriptor()const;

protected:

virtualIBinder*onAsBinder();

};

 

是一个模板类,继承了BBinder,还有模板INTERFACE。

我们刚才已经看过,BBinder没有实现queryLocalInterface(),而BnInterface返回自己,可以他并没有继承IInterface,怎么可以强制转换呢,唯一的解释就是INTERFACE模板必须继承和实现IInterface.

classIInterface:

publicvirtualRefBase

{

public:

IInterface();

spasBinder();

spasBinder()const;

protected:

virtual~IInterface();

virtualIBinder*onAsBinder()=0;

};

 

这也太简单了吧,只是定义了从Interface到IBinder的转换接口asBinder,而刚才我们研究的queryLocalInterface()正好反过来,说明IBinder和IInterface之间是可以互转的,一个人怎么可以变成另外一个人呢?

唯一的解释就是这个人有双重性格,要么他同时继承IInterface和IBinder,要么他体内有这两个对象同时存在,不卖关子了,在服务端,这个双重性格的人就是BnXXX,XXX代表某个具体的服务,我们以图中的BnMediaPlayer为例,看看他的定义

classBnMediaPlayer:

publicBnInterface

{

public:

virtualstatus_tonTransact(uint32_tcode,

constParcel&data,

Parcel*reply,

uint32_tflags=0);

};

classIMediaPlayer:

publicIInterface

{

public:

DECLARE_META_INTERFACE(MediaPlayer);

...

}

 

这下本性都露出来了,IBinder和IInterface的影子都露出来了,让我们用图梳理一下(箭头代表继承关系)

             

归纳一下,

1. BBinder实现了大部分的IBinder接口,除了onTransact()和queryLocalInterface(),getInterfaceDescriptor();

2. BnInterface实现了IBinder的queryLocalInterface()和getInterfaceDescriptor(),但是其必须借助实际的接口类。

3. BnMediaPlayer只是定义了onTransact(),没有实现。

4. onTransact()的具体实现在Client类。

为什么搞得那么复杂?

Google是希望通过这些封装尽可能减少开发者的工作量,开发一个native的service开发者只需要做这么几件事(上图中深色部分):

1.定义一个接口文件,IXXXService,继承IInterface

2.定义BnXXX(),继承BnInterface

3.实现一个XXXService类,继承BnXXX(),并具体实现onTransact()函数。

那客户端呢?

我们的目标是找到一个类,它必须同时拥有IBinder和IIterface的特性,先看看BpBinder吧

   

classBpBinder:

publicIBinder

 

跟IInterface没有关系,那一定是别人,看看BpInterface吧,

template

classBpInterface:

publicINTERFACE,publicBpRefBase

{

public:

BpInterface(constsp&remote);

protected:

virtualIBinder*onAsBinder();

};

 

我们刚才已经知道了,INTERFACE是IMediaPlayer,它继承了IInterface,IInterface的对象找到了,但跟IBinder没关系?

只剩下BpRefBase了,

classBpRefBase:

publicvirtualRefBase

{

protected:

...

inlineIBinder*remote(){returnmRemote;}

...

private:

...

IBinder*constmRemote;

RefBase:

:

weakref_type*mRefs;

volatileint32_tmState;

};

 

 有了,BpRefBase里有IBinder成员变量,看来在客户端,没有一个类同时继承IBinder和IInterface,但是有一个类继承了其一,但包含了另外一个,这种在设计模式里成为组合(Composition).

 还是不太明白?

还是用图解释吧,

 

看明白了?

从BpInterface开始,通过BpRefBase我们可以找到IBinder,这个转换就在asBinder()的实现里,看看代码

spIInterface:

:

asBinder(){

returnthis?

onAsBinder():

NULL;

}

spIInterface:

:

asBinder()const{

returnthis?

const_cast(this)->onAsBinder():

NULL;

}

template

inlineIBinder*BpInterface:

:

onAsBinder()

{

returnremote();

}

template

IBinder*BnInterface:

:

onAsBinder()

{

returnthis;

}

这里印证我们上面两张图的正确性,onAsBinder是转换的发生的地方,服务端(BnInterface)的实现直接返回了自己,因为它继承了两者,而客户端(BpInterface)则需要通过remote()(返回mRemote成员变量)获取,因为他自己本身不是IBinder,

那个BpRefbase的mRemote是如何被赋值的?

看看以下代码

//frameworks/native/libs/binder/binder.cpp

BpRefBase:

:

BpRefBase(constsp&o)

:

mRemote(o.get()),mRefs(NULL),mState(0)

{

...

}

 

//frameworks/native/include/binder/iinterface.h

template

inlineBpInterface:

:

BpInterface(constsp&remote)

:

BpRefBase(remote)

{

}

 

//frameworks/av/media/libmedia/IMediaPlayer.cpp

classBpMediaPlayer:

publicBpInterface

{

public:

BpMediaPlayer(constsp&impl)

:

BpInterface(impl)

{

}

...

}

 

原来是从子类一级一级注入的,那唯一的问题就是在哪里完成这个注入操作,马上搜索"newBpMediaPlayer",奇怪,竟然没有,试试搜索"IMediaPlayer“,发现了一点线索

//av/media/libmedia/IMediaPlayerService.cpp

70:

virtualspcreate(

71:

constsp&client,intaudioSessionId){

72Parceldata,reply;

73:

...

77remote()->transact(CREATE,data,&reply);

78:

returninterface_cast(reply.readStrongBinder());//reply里读出IBinder,然后转成IMediaPlayer接口对象

79}

 

这里通过interface_cast直接把IBinder转换成了IMediaPlayer,interface_cast到底有什么魔力?

template

inlinespinterface_cast(constsp&obj)

{

returnINTERFACE:

:

asInterface(obj);

}

 

继续跟进asInterface,结果发现里以下代码

#defineDECLARE_META_INTERFACE(INTERFACE)\

staticconstandroid:

:

String16descriptor;\

staticandroid:

:

spasInterface(\

constandroid:

:

sp

:

IBinder>&obj);\

virtualconstandroid:

:

String16&getInterfaceDescriptor()const;\

I##INTERFACE();\

virtual~I##INTERFACE();\

 

#defineIMPLEMENT_META_INTERFACE(INTERFACE,NAME)\

constandroid:

:

String16I##INTERFACE:

:

descriptor(NAME);\

constandroid:

:

String16&\

I##INTERFACE:

:

getInterfaceDescriptor()const{\

returnI##INTERFACE:

:

descriptor;\

}\

android:

:

spI##INTERFACE:

:

asInterface(\

constandroid:

:

sp

:

IBinder>&obj)\

{\

android:

:

spintr;\

if(obj!

=NULL){\

intr=static_cast(\

obj->queryLocalInterface(\

I##INTERFACE:

:

descriptor).get());\

if(intr==NULL){\

intr=newBp##INTERFACE(

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 其它课程

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1