要想使用服务端,首先要获取服务端在Binder驱动中对应的mRemote变量的引用。获得该变量的引用后,就可以调用该变量的transact()方法。该方法的函数原型如下:
public final boolean transact(int code, Parcel data, Parcel reply,int flags)
其中data表示的是要传递给远程Binder服务的包裹(Parcel),远程服务函数所需要的参数必须放入这个包裹中。包裹中只能放入特定类型的变量,这些类型包括常用的原子类型,比如String、int、long等,要查看包裹可以放入的全部数据类型,可以参照Parcel类。除了一般的原子变量外,Parcel还提供了一个writeParcel()方法,可以在包裹中包含一个小包裹。因此,要进行Binder远程服务调用时,服务函数的参数要么是一个原子类,要么必须继承于Parcel类,否则,是不能传递的。
因此,对于MusicPlayerService的客户端而言,可以如下调用transact()方法。
IBinder mRemote = null;
String filePath = "/sdcard/music/heal_the_world.mp3";
int code = 1000;
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken("MusicPlayerService");
data.writeString(filePath);
mRemote.transact(code, data, reply, 0);
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
现在来分析以上代码。首先,包裹不是客户端自己创建的,而是调用Parcel.obtain()申请的,这正如生活中的邮局一样,用户一般只能用邮局提供的信封(尤其是EMS)。其中data和reply变量都由客户端提供,reply变量用户服务端把返回的结果放入其中。
writeInterfaceToken()方法标注远程服务名称,理论上讲,这个名称不是必需的,因为客户端既然已经获取指定远程服务的Binder引用,那么就不会调用到其他远程服务。该名称将作为Binder驱动确保客户端的确想调用指定的服务端。
writeString()方法用于向包裹中添加一个String变量。注意,包裹中添加的内容是有序的,这个顺序必须是客户端和服务端事先约定好的,在服务端的onTransact()方法中会按照约定的顺序取出变量。
接着调用transact()方法。调用该方法后,客户端线程进入Binder驱动,Binder驱动就会挂起当前线程,并向远程服务发送一个消息,消息中包含了客户端传进来的包裹。服务端拿到包裹后,会对包裹进行拆解,然后执行指定的服务函数,执行完毕后,再把执行结果放入客户端提供的reply包裹中。然后服务端向Binder驱动发送一个notify的消息,从而使得客户端线程从Binder驱动代码区返回到客户端代码区。
transact()的最后一个参数的含义是执行IPC调用的模式,分为两种:一种是双向,用常量0表示,其含义是服务端执行完指定服务后会返回一定的数据;另一种是单向,用常量1表示,其含义是不返回任何数据。
最后,客户端就可以从reply中解析返回的数据了,同样,返回包裹中包含的数据也必须是有序的,而且这个顺序也必须是服务端和客户端事先约定好的。
分享到:
相关推荐
这种设计使得客户端看似直接调用远程服务,实际上所有通信都在Binder驱动的调度下进行。 **5.2 设计Service端** 创建一个基于Binder的服务端非常简单,只需继承Binder类并创建一个新的服务类。例如,我们创建一个`...
Binder的设计围绕Client-Server模型展开,其中服务器端负责提供服务,客户端则请求并使用这些服务。这种模型在Android中尤为常见,从媒体播放到传感器数据处理,无不体现出Binder的重要性。Binder通信协议设计精巧,...
### Android Binder设计与实现 #### 一、引言与背景 随着智能手机的普及与功能的多样化,Android系统作为主流移动操作系统之一,面临着越来越多的应用场景需求。为了满足这些需求,Android系统内部采用了一种高效...
Binder引入了身份验证机制,每个进程都有唯一的UID/PID,数据包在传输时会附带发送方的UID/PID,接收方可以在内核级别验证,增强了安全性。此外,Binder支持实名和匿名通信,实名Binder提供明确的访问控制,而匿名...
文中的内容主要围绕Android系统中的Binder机制展开,这是一种核心的进程间通信(IPC)方式,由Binder驱动、Binder服务器和Binder客户端组成。Binder在Android系统中扮演着远程过程调用(RPC)的角色,允许在一个进程...
4. **线程模型**:Binder默认使用单线程模型,即每个Binder客户端和服务器端都在自己的线程中执行。不过,可以通过自定义线程池来优化并发性能。 5. **内存管理**:Binder使用了虚拟内存技术,实现了跨进程的数据...
Binder是Android系统内核中的一个组件,它充当了进程间通信的桥梁。与其他IPC方式相比,Binder具有高效、安全和可管理性等优点。在Android中,许多系统服务,如Activity Manager、Content Provider等,都是通过...
其设计模式基于客户端-服务器(Client-Server)架构,其中提供服务的一方称为Server进程,请求服务的一方称为Client进程。 **服务组件与客户端组件**: - **Service组件**:在Server进程中运行,可提供多种服务功能...
1. **客户端发送请求**:客户端创建一个 Binder 对象,并将其通过 Binder 驱动发送到服务端。 2. **服务端处理请求**:服务端接收到 Binder 对象后,根据类型和标志进行相应的处理。 3. **返回结果**:服务端处理...
数据通过Parcel对象进行序列化和反序列化,服务端和客户端之间的方法调用则通过Binder接口的实现进行。 Binder通信协议允许跨进程的异步调用,支持回调和结果返回,使得远程调用如同本地调用一样简单。 **3. Binder...
Binder采用的是典型的客户端-服务器模型(Client-Server Model)。在这一模型中,一个进程充当服务提供者(Server),而其他进程则作为服务请求者(Client)。Server通常负责管理和提供特定的服务,而Client通过Binder机制...
下面我们将详细探讨Binder机制以及如何在Native层实现Binder客户端。 首先,让我们了解Binder的基本概念。Binder是Android特有的IPC机制,由三部分组成:Client、Service和Binder驱动。Client是请求服务的进程,...
3. Binder驱动:在内核层,负责管理Binder通信的底层实现,包括消息传递、线程调度等。 三、Binder通信流程 1. 创建服务:服务端通过AIDL(Android Interface Definition Language)定义接口,并实现接口类。 2. ...
Binder是Android系统内核中的一个组件,它为应用程序提供了安全、高效的IPC方式。在Binder机制中,服务端(Server)运行在一个独立的进程中,而客户端(Client)则通过Binder接口与其通信。当客户端调用服务端的...
5. Binder对象和引用:Binder对象是指服务端提供的具体服务,而Binder引用是指客户端对服务对象的引用。Binder对象可以是任意复杂度的对象,通过Binder引用,客户端可以远程调用服务端的方法。 Binder机制的通信...
【Android Binder设计与实现】 Binder是Android操作系统中的核心组件,它是Android系统进程间通信(IPC)的主要机制。与其他Linux环境下的IPC方式如管道、System V IPC、socket等相比,Binder具有独特的优势,使得...
Binder的设计和实现来源于OpenBinder项目,最初是由Be公司作为“下一代BeOS”开发的一部分。后来,PalmSource收购了Be公司,并在Palm Cobalt(一个基于微内核的操作系统)中首次实现了Binder。当Palm转向使用Linux...
3. **简洁性**:Binder的设计较为简单明了,易于理解和实现。 4. **统一性**:Binder机制不仅适用于C/C++环境,还适用于Java环境,使得整个Android平台的IPC机制更加统一和一致。 #### Binder机制的关键组成部分 -...
Binder通信涉及到客户端(Client)、服务器端(Server)和Binder驱动(Binder Driver)。当一个应用需要调用另一个应用的服务时,会创建一个Binder对象,这个对象被传递到服务进程中,由服务进程的Binder代理处理...