android进程间通信之Binder学习笔记(一)

Binder

Binder 是一种进程间通信机制,基于开源的 OpenBinder 实现;OpenBinder 起初由 Be Inc. 开发,后由 Plam Inc. 接手。

从字面上来解释 Binder 有胶水、粘合剂的意思,顾名思义就是粘和不同的进程,使之实现通信。

Android系统是基于Linux系统的,理论上应该使用Linux内置的IPC方式。Linux中的IPC方式有管道、信号量、共享内存、消息队列、Socket,Android使用的Binder机制不属于Linux。

Android不继承Linux中原有的IPC方式,而选择使用Binder,说明Binder具有一定的优势。

为什么使用Binder

  • 通信方式 编程过程中,常常会用到Client-Server的通信方式,但在Linux的五种IPC机制中,只有Socket支持这种通信方式。
  • 传输性能 Socket作为一款通用接口,其传输效率低,开销大,主要用在跨网络的进程间通信和本机上进程间的低速通信;消息队列和管道采用存储-转发方式,即数据先从发送方拷贝到内存开辟的缓存区中,然后再从内核缓存区拷贝到接收方缓存区,至少有两次拷贝过程;共享内存虽然无需拷贝,但控制复杂,难以使用;而Binder只需要拷贝一次;
  • 安全性 Android作为一个开放式的平台,应用程序的来源广泛,因此确保只能终端的安全是非常重要的。Linux传统的IPC没有任何安全措施,完全依赖上层协议来确保,具体有以下两点表现:
    第一,传统IPC的接收方无法获得对方可靠的UID/PID(用户ID/进程ID),从而无法鉴别对方身份,使用传统IPC时只能由用户在数据包里填入UID/PID,但这样不可靠,容易被恶意程序利用;
    第二,传统IPC的访问接入点是开放的,无法建立私有通信,只要知道这些接入点的程序都可以和对端建立连接,这样无法阻止恶意程序通过猜测接收方的地址获得连接。

Binder 通信原理

image.png

Binder主要分为四个模块:

  • Client进程 客户端,例如各个app
  • Server进程 服务器
  • Binder驱动 驱动,运行在内核态
  • ServiceManager 服务器管理进程

Binder驱动 和 Service Manager进程 属于 Android基础架构(即系统已经实现好了);而Client 进程 和 Server 进程 属于Android应用层(需要开发者自己实现)。

service manager

Service Manager是一个linux级的进程,顾名思义,就是service的管理器。

这里的service的概念和init过程中init.rc中的service是不同,init.rc中的service是都是linux进程,但是这里的service它并不一定是一个进程,也就是说可能一个或多个service属于同一个linux进程。

任何service在被使用之前,均要向SM(Service Manager)注册,同时客户端需要访问某个service时,应该首先向SM查询是否存在该服务。

如果SM存在这个service,那么会将该service的handle返回给client,handle是每个service的唯一标识符。

SM的入口函数在service_manager.c中,用兴趣的可以查看下。

int main(int argc, char **argv)
{
    struct binder_state *bs;
    void *svcmgr = BINDER_SERVICE_MANAGER;

    bs = binder_open(128*1024);

    if (binder_become_context_manager(bs)) {
        LOGE("cannot become context manager (%s)/n", strerror(errno));
        return -1;
    }

    svcmgr_handle = svcmgr;
    binder_loop(bs, svcmgr_handler);
    return 0;
}

这里不在过多解释,本篇只介绍如何使用Binder

Binder驱动

Binder驱动是Binder机制中进行进程间通讯的介质。
Binder驱动会对具有跨进程传递能力的对象做特殊处理,自动完成代理对象和本地对象的转换。说白了就是一种地址映射。

具体机制来自于一遍博客,在参考中已经列出,画的很详细:


image.png

通信步骤

使用Binder实现通信大致分为四步:
1.注册服务(将服务器端注册到ServiceManager)
2. 获取服务(客户端获取服务端信息)
3. 使用服务(j调用返回的代理服务器,向服务器端发送数据)
4. 接受服务(服务器端,即可接受到数据,实现通信过程)

参考

Android跨进程通信:图文详解 Binder机制 原理
一篇文章了解相见恨晚的 Android Binder 进程间通讯机制

你可能感兴趣的:(android进程间通信之Binder学习笔记(一))