Binder是Android系统结合自身系统任务特点而实现的一种与传统方式不一样的IPC(Inter-Process Communication)机制。
传统的IPC方式有:管道、FIFO、信号、消息队列、信号量、共享内存、Socket。 |
Unix最初只有:管道、FIFO(命名管道)、信号等IPC机制,后来Linux继承和发展了Unix系统的IPC,对其影响比较大的有AT&T的贝尔实验室及BSD。但侧重点有所不同,前者对Unix早期的进程间通信手段进行了系统的改进和扩充,形成了“system V IPC”的消息队列、信号量、共享内存,通信进程局限在单个计算机内;后者则跳过了该限制,形成了基于套接口(socket)的进程间通信机制。
Android是基于Linux的操作系统,而由于Android系统自身任务特点(基于组件方式、扁平化处理、多服务模式),弱化了进程间通信过程,而强调组件方式(四大组件:activity、service、content provider、broadcast receiver)使得传统方式在效率、模式等方面都不大适合,最终有了全新的IPC过程——Binder。
基于Binder的IPC实现过程:
1. 在内核空间创建一个虚拟设备,并生成一个虚拟设备文件“/dev/binder”
2. 利用mmap()接口,把上述创建的内核设备文件的一段空间映射到用户空间
3. 当两个进程进行通信时,只需要一次内存拷贝
4. 系统为每个应用分配UID,可靠的身份标记只有由IPC机制本身在内核中添加(传统IPC只能由用户在数据包里填入UID/PID,这样不可靠,容易被恶意程序利用)。
5. 其次传统IPC访问接入点是开放的,无法建立私有通道。
Android的IPC过程主要是C-S模式的,通信过程需要涉及到应用空间与内核空间。
在应用空间,其通信过程需要涉及到三方:Client(Binder代理端)、Server(Binder响应端)、ServiceManager(管理所有Binder响应端,即所有Service)。
在内核空间,主要与Binder虚拟设备驱动有关(/dev/binder)。
Binder通信的核心是在于其内核空间部分的实现上。 |
Binder在通信过程中主要实现两个功能:数据传输、RPC(Remote Procedure Call)。 |
Binder的数据传输通信过程可以简化成如下图所示:
但是前面说过,Binder的通信主要完成两个过程:数据传输、RPC过程,上图只是给出了Binder的数据传输过程模型,然而其RPC过程是基于数据传输过程来实现的,其基本框图最终可以简化成如下图所示:
在Binder通信过程中,客户端如果需要使用服务端的服务之前,都需要获取对应服务端的Binder代理,对于与ServiceManager(也是一个Binder服务端)通信过程也不例外。只不过,ServiceManager可以看成是一个特殊的Service,其服务代理端获取过程也是比较特殊的(因为ServiceManager的Binder代理的引用句柄等于0,其他所有客户端使用其功能都可以通过句柄0来获取其代理)。除此之外,其他所有服务端的Binder代理都是需要通过访问ServiceManager来直接或者间接获取的(间接获取就是先通过servicemanager获取一个服务的binder代理,然后再访问这个服务来获得另外一个目的服务的代理)。
在讲述Binder的通信过程之前,有必要先呈现一下其涉及到对象的数据结构及继承过程。
Binder代理端的Proxy接口及继承过程:
class RefBase {}
class IInterface : public virtual RefBase
class BpRefBase : public virtual RefBase
class IMediaPlayerService: public IInterface
class BpInterface : public IMediaPlayerService, public BpRefBase
class BpMediaPlayerService: public BpInterface<IMediaPlayerService>
//BpMediaPlayerService构造函数,handle为Binder引用代理句柄
explicit BpMediaPlayerService(const sp<IBinder>& impl = BpBinder(handle))
: BpInterface<IMediaPlayerService>(impl){}
Binder响应的本地端Native接口及继承过程:
class IBinder : public virtual RefBase
class IInterface : public virtual RefBase
class BBinder : public IBinder
class IMediaPlayerService: public IInterface
class BnInterface : public IMediaPlayerService, public BBinder //IMediaPlayerService是模版传入
class BnMediaPlayerService: public BnInterface<IMediaPlayerService>
class MediaPlayerService : public BnMediaPlayerService
其结构中涉及到两个比较重要的宏定义,主要用于实现RPC过程,因为不管是代理端还是响应端,其数据结构的继承关系中都会去继承IMediaPlayerService,展开如下:
DECLARE_META_INTERFACE
路径:IMediaPlayerService.h (../../media/libmedia/include/media/IMediaPlayerService.h)
DECLARE_META_INTERFACE(MediaPlayerService) 宏展开过程如下:
static const ::android::String16 descriptor;
static ::android::sp<IMediaPlayerService> asInterface(const ::android::sp<::android::IBinder>& obj);
virtual const ::android::String16& getInterfaceDescriptor() const;
IMediaPlayerService();
virtual ~IMediaPlayerService();
IMPLEMENT_META_INTERFACE
路径:IMediaPlayerService.cpp (../../media/libmedia/include/media/IMediaPlayerService.cpp)
IMPLEMENT_META_INTERFACE(MediaPlayerService, “android.media.IMediaPlayerService”) 宏展开过程如下:
const ::android::String16 IMediaPlayerService::descriptor("android.media.IMediaPlayerService");
const ::android::String16& IMediaPlayerService::getInterfaceDescriptor() const
{
return IMediaPlayerService::descriptor;
}
IBinder::queryLocalInterface() //Binder.cpp (native\libs\binder)
class BpMediaPlayerService: public BpInterface<IMediaPlayerService> //IMediaPlayerService.cpp (av\media\libmedia)
explicit BpMediaPlayerService(const sp<IBinder>& impl) //BpMediaPlayerService构造函数
: BpInterface<IMediaPlayerService>(impl)
{}
::android::sp<IMediaPlayerService> IMediaPlayerService::asInterface(const ::android::sp<::android::IBinder>& obj)
{
::android::sp<IMediaPlayerService> intr;
if (obj != NULL) {
intr = static_cast<IMediaPlayerService*>(obj->queryLocalInterface(IMediaPlayerService::descriptor).get());
//IBinder::queryLocalInterface()查询都是返回空的
if (intr == NULL) {
intr = new BpMediaPlayerService(obj);
}
}
return intr;
}
IMediaPlayerService::IMediaPlayerService() {}
IMediaPlayerService::~IMediaPlayerService() {}
宏中最重要的一个函数就是IMediaPlayerService::asInterface,告知如何生成一个客户端的Binder代理过程,在此不会详细展开讲解,因为只是概述,后续章节会详细介绍。
以上只是Android Binder机制的简单概述,主要做为后续章节的引言,在接下去的章节中,会详细介绍数据的交互过程以及RPC过程。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/36314.html