Android has a lightweight mechanism for remote procedure calls (RPCs) — where a method is called locally, but executed remotely (in another process), with any result returned back to the caller. This entails decomposing the method call and all its attendant data to a level the operating system can understand, transmitting it from the local process and address space to the remote process and address space, and reassembling and reenacting the call there. Return values have to be transmitted in the opposite direction. Android provides all the code to do that work, so that you can concentrate on defining and implementing the RPC interface itself.
An RPC interface can include only methods. All methods are executed synchronously (the local method blocks until the remote method finishes), even if there is no return value.
In brief, the mechanism works as follows: You'd begin by declaring the RPC interface you want to implement using a simple IDL (interface definition language). From that declaration, the aidl tool generates a Java interface definition that must be made available to both the local and the remote process. It contains two inner class, as shown in the following diagram:
The inner classes have all the code needed to administer remote procedure calls for the interface you declared with the IDL. Both inner classes implement the IBinder interface. One of them is used locally and internally by the system; the code you write can ignore it. The other, called Stub, extends the Binder class. In addition to internal code for effectuating the IPC calls, it contains declarations for the methods in the RPC interface you declared. You would subclass Stub to implement those methods, as indicated in the diagram.
Typically, the remote process would be managed by a service (because a service can inform the system about the process and its connections to other processes). It would have both the interface file generated by the aidl tool and the Stub subclass implementing the RPC methods. Clients of the service would have only the interface file generated by the aidl tool.
Here's how a connection between a service and its clients is set up:
• Clients of the service (on the local side) would implement onServiceConnected() and onServiceDisconnectedn methods so they can be notified when a successful connection to the remote service is established, and when it goes away. They would then call bindServicen to set up the connection.
• The service's onBindn method would be implemented to either accept or reject the connection, depending on the intent it receives (the intent passed to bindService()). If the connection is accepted, it returns an instance of the Stub subclass.
• If the service accepts the connection, Android calls the client's onServiceConnected() method and passes it an IBinder object, a proxy for the Stub subclass managed by the service. Through the proxy, the client can make calls on the remote service.
This brief description omits some details of the RPC mechanism. For more information, see Designing a Remote Interface Using AIDL and the IBinder class description.
Was this article helpful?