现在的位置: 首页 > 综合 > 正文

【内核研究】Binder框架概述

2017年02月09日 ⁄ 综合 ⁄ 共 1091字 ⁄ 字号 评论关闭

Binder,英文的意思是别针、回形针。我们经常用别针把两张纸"别"在一起,而在Android中,Binder用于完成进程间通信(IPC),即把多个进程"别"在一起。比如,普通应用程序可以调用音乐播放服务提供的播放、暂停、停止等功能。

Binder工作在Linux层面,属于一个驱动,只是这个驱动不需要硬件,或者说其操作的硬件是基于一小段内存。从线程的角度来讲,Binder驱动代码运行在内核态,客户端程序调用Binder是通过系统调用完成的。

Binder是一种架构,这种架构提供了服务端接口、Binder驱动、客户端接口三个模块,如图所示。

首先来看服务端。一个Binder服务端实际上就是一个Binder类的对象,该对象一旦创建,内部就启动一个隐藏线程。该线程接下来会接收Binder驱动发送的消息,收到消息后,会执行到Binder对象中的onTransact()函数,并按照该函数的参数执行不同的服务代码。因此,要实现一个Binder服务,就必须重载onTransact()方法。

可以想象,重载onTransact()函数的主要内容是把onTransact()函数的参数转换为服务函数的参数,而onTransact()函数的参数来源是客户端调用transact()函数时输入的,因此,如果transact()有固定格式的输入,那么onTransact()就会有固定格式的输出。

下面再看Binder驱动。任意一个服务端Binder对象被创建时,同时会在Binder驱动中创建一个mRemote对象,该对象的类型也是Binder类。客户端要访问远程服务时,都是通过mRemote对象。

最后来看应用程序客户端。客户端要想访问远程服务,必须获取远程服务在Binder对象中对应的mRemote引用。获得该mRemote对象后,就可以调用其transact()方法,而在Binder驱动中,mRemote对象也重载了transact()方法,重载的内容主要包括以下几项。

以线程间消息通信的模式,向服务端发送客户端传递过来的参数。

挂起当前线程,当前线程正是客户端线程,并等待服务端线程执行完指定服务函数后通知(notify)。

接收到服务端线程的通知,然后继续执行客户端线程,并返回到客户端代码区。

从这里可以看出,对应用程序开发员来讲,客户端似乎是直接调用远程服务对应的Binder,而事实上则是通过Binder驱动进行了中转。即存在两个Binder对象,一个是服务端的Binder对象,另一个则是Binder驱动中的Binder对象,所不同的是Binder驱动中的对象不会再额外产生一个线程。

抱歉!评论已关闭.