Android 远程过程调用

Android 有一个轻量级的远程过程调用(RPC)机制:即在本地调用一个方法,但在远程(其它的进程中)进行处理,然后将结果返回调用者。

这将方法调用及其附属的数据以系统可以理解的方式进行分离,并将其从本地进程和本地地址空间传送至远程过程和远程地址空间,并在那里重新装配并对调用做出反应。

返回的结果将以相反的方向进行传递。Android 提供了完成这些工作所需的所有的代码,以使你可以集中精力来实现RPC 接口本身。

RPC 接口可以只包括方法。即便没有返回值,所有方法仍以同步的方式执行(本地方法阻塞直至远程方法结束)。

简单的说,这套机制是这样工作的:一开始,你用简单的ID L(界面描绘语言)声明一个你想要实现的RPC接口。

然后用aidl 工具为这个声明生成一个Java 接口定义,这个定义必须对本地和远程进程都可见。

内部类中有管理实现了你用IDL 声明的接口的远程方法调用所需要的所有代码。

两个内部类均实现了IBinder 接口。一个用于系统在本地内部使用,你些的代码可以忽略它;另外一个,我们称为Stub,扩展了Binder 类。

除了实现了IPC 调用的内部代码之外,它还包括了你声明的RPC 接口中的方法的声明。

一般情况下,远程过程是被一个服务所管理的(因为服务可以通知系统关于进程以及它连接到别的进程的信息)。它包含着aidl 工具产生的接口文件和实现了RPC 方法的Stub 的子类。而客户端只需要包括aidl 工具产生的接口文件。

下面将说明服务与其客户端之间的连接是如何建立的:

• 服务的客户端(位于本地)应该实现onServiceConnected() 和 onServiceDisconnected() 方法。这样,当至远程服务的连接成功建立或者断开的时候,它们会收到通知。这样它们就可以调用bindService() 来设置连接。

• 而服务则应该实现onBind() 方法以接受或拒绝连接。这取决于它收到的intent(intent 将传递给bindService())。如果接受了连接,它会返回一个Stub 的子类的实例。

• 如果服务接受了连接,Android 将会调用客户端的onServiceConnected() 方法,并传递给它一个IBinder 对象,它是由服务所管理的Stub 的子类的代理。通过这个代理,客户端可以对远程服务进行调用。