Android使用AIDL实现进程间通信

为使应用程序之间能够彼此通信,Android提供了IPC (Inter Process Communication,进程间通信)的一种独特实现: AIDL (Android Interface Definition Language, Android接口定义语言)。

在Android中,每个应用(Application)执行在它自己的进程中,无法直接调用到其他应用的资源,这也符合“沙箱”的理念。因此,在Android中,当一个应用被执行时,一些操作是被限制的,比如访问内存,访问传感器,等等。这样做可以最大化地保护系统,免得应用程序“为所欲为”。那我们有时需要在应用间交互,怎么办呢?于是,Android需要实现IPC协议。然而,这个协议还是有点复杂,主要因为需要实现数据管理系统(在进程或线程间传递数据)。为了暂时减缓这个麻烦,Android为我们实现了自己的IPC,也就是是AIDL 。

AIDL(Android Interface Definition Language)是一种接口定义语言,编译器通过*.aidl文件的描述信息生成符合通信协议的Java代码,我们无需自己去写这段繁杂的代码,只需要在需要的时候调用即可,通过这种方式我们就可以完成进程间的通信工作。

AIDL是IPC的一个轻量级实现,用了对于Java开发者来说很熟悉的语法。Android也提供了一个工具,可以自动创建Stub(类构架,类骨架)。当我们需要在应用间通信时,我们需要按以下几步走: 1. 定义一个AIDL接口 2. 为远程服务(Service)实现对应Stub 3. 将服务“暴露”给客户程序使用

4. 客户端调用

接下来,我就演示一个操作AIDL的最基本的流程。

一、创建工程

首先,我们需要建立一个服务端的工程,如图所以:

在com.scott.aidl这个包中,新建一个普通文件(New->File),取名为IPerson.aidl。在这个文件中定义了一个“问候”的方法:

package com.scott.aidl;interface IPerson {String greet(String someone);} 一旦文件被保存,Android的AIDL工具会在gen/com/scott/aidl这个文件夹里自动生成对应的IPerson.java这个文件。因为是自动生成的,所以无需改动。这个文件里就包含了Stub,我们接下来要为我们的远程服务实现这个Stub。格式化后的代码: package com.scott.aidl;public interface IPerson extends android.os.IInterface {/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implements com.scott.aidl.IPerson {private static final java.lang.String DESCRIPTOR = "com.scott.aidl.IPerson";/** Construct the stub at attach it to the interface. */public Stub() {this.attachInterface(this, DESCRIPTOR);}/*** Cast an IBinder object into an com.scott.aidl.IPerson interface,* generating a proxy if needed.*/public static com.scott.aidl.IPerson asInterface(android.os.IBinder obj) {if ((obj == null)) {return null;}android.os.IInterface iin = (android.os.IInterface) obj.queryLocalInterface(DESCRIPTOR);if (((iin != null) && (iin instanceof com.scott.aidl.IPerson))) {return ((com.scott.aidl.IPerson) iin);}return new com.scott.aidl.IPerson.Stub.Proxy(obj);}public android.os.IBinder asBinder() {return this;}@Overridepublic boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags)throws android.os.RemoteException {switch (code) {case INTERFACE_TRANSACTION: {reply.writeString(DESCRIPTOR);return true;}case TRANSACTION_greet: {data.enforceInterface(DESCRIPTOR);java.lang.String _arg0;_arg0 = data.readString();java.lang.String _result = this.greet(_arg0);reply.writeNoException();reply.writeString(_result);return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements com.scott.aidl.IPerson {private android.os.IBinder mRemote;Proxy(android.os.IBinder remote) {mRemote = remote;}public android.os.IBinder asBinder() {return mRemote;}public java.lang.String getInterfaceDescriptor() {return DESCRIPTOR;}public java.lang.String greet(java.lang.String someone) throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();java.lang.String _result;try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeString(someone);mRemote.transact(Stub.TRANSACTION_greet, _data, _reply, 0);_reply.readException();_result = _reply.readString();} finally {_reply.recycle();_data.recycle();}return _result;}}static final int TRANSACTION_greet = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);}public java.lang.String greet(java.lang.String someone) throws android.os.RemoteException;}

该文件的大纲视图如下:

“人”的结构就是相互支撑,“众”人的事业需要每个人的参与。

Android使用AIDL实现进程间通信

相关文章:

你感兴趣的文章:

标签云: