我们都知道在Android中的每一个应用是一个进程,其实每一个应用就相当于Linux系统里面的一个用户,进程和进程之间的通信其实就相当于用户和用户之间的通信,为了实现这种跨进程通信,Android提供了AIDL Service (Android Interface definition language).

与邦等本地Service不同的是,本地Service的onBind()方法会直接把IBinder对象本身传给客户端的ServiceConnection的onServiceConnected方法的第二个参数。但远程Service的onBind()方法只是将IBinder对象的代理传给客户端的ServiceConnection的onService Connected方法的第二个参数。

ALDL定义的特点:

1、AIDL定义接口的源码必须以.aidl结尾。

2、AIDL接口中用到数据类型,除了基本类型、String、List、Map、CharSequence之外,其他类型全部都需要导包,即使它们在同一个包中也需要导包。

下面来具体实现一个示例:

(1)定义AIDL接口(和Java接口非常类似)

package com.example.testservice;interface ICat {String getColor();double getWeight();}

(2)定以好上面接口后保存,ADT工具会自动在gen.com.example.service目录下生成一个ICat.jar接口,在该接口中包含一个Stub内部类,该内部类实现了IBinder、ICat两个接口,这个Stub类将会作为远程Service的回调类——它实现了IBuilder接口,因此可作为Service的onBind()方法的返回值。这个Stub类就是一个代理类,同样可以实现IBinder的功能,并且还额外实现了ICat远程访问的功能。


自动生成的ICat.java接口

/* * This file is auto-generated.  DO NOT MODIFY. * Original file: D:\\adt-bundle-windows-x86-20130729\\eclipse\\workspace\\TestService\\src\\com\\example\\testservice\\ICat.aidl */package com.example.testservice;public interface ICat extends android.os.IInterface {/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implementscom.example.testservice.ICat {private static final java.lang.String DESCRIPTOR = "com.example.testservice.ICat";/** Construct the stub at attach it to the interface. */public Stub() {this.attachInterface(this, DESCRIPTOR);}/** * Cast an IBinder object into an com.example.testservice.ICat * interface, generating a proxy if needed. */public static com.example.testservice.ICat asInterface(android.os.IBinder obj) {if ((obj == null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin != null) && (iin instanceof com.example.testservice.ICat))) {return ((com.example.testservice.ICat) iin);}return new com.example.testservice.ICat.Stub.Proxy(obj);}@Overridepublic 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_getColor: {data.enforceInterface(DESCRIPTOR);java.lang.String _result = this.getColor();reply.writeNoException();reply.writeString(_result);return true;}case TRANSACTION_getWeight: {data.enforceInterface(DESCRIPTOR);double _result = this.getWeight();reply.writeNoException();reply.writeDouble(_result);return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements com.example.testservice.ICat {private android.os.IBinder mRemote;Proxy(android.os.IBinder remote) {mRemote = remote;}@Overridepublic android.os.IBinder asBinder() {return mRemote;}public java.lang.String getInterfaceDescriptor() {return DESCRIPTOR;}@Overridepublic java.lang.String getColor()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);mRemote.transact(Stub.TRANSACTION_getColor, _data, _reply,0);_reply.readException();_result = _reply.readString();} finally {_reply.recycle();_data.recycle();}return _result;}@Overridepublic double getWeight() throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();double _result;try {_data.writeInterfaceToken(DESCRIPTOR);mRemote.transact(Stub.TRANSACTION_getWeight, _data, _reply,0);_reply.readException();_result = _reply.readDouble();} finally {_reply.recycle();_data.recycle();}return _result;}}static final int TRANSACTION_getColor = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);static final int TRANSACTION_getWeight = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);}public java.lang.String getColor() throws android.os.RemoteException;public double getWeight() throws android.os.RemoteException;}
(3)定义一个Service实现类,该Service的onBind()方法所返回的IBinder对象应该是ADT所生成的ICat.Stub的子类的实例。这一步的主要作用是将上面创建的接口暴漏给客户端。

package com.example.testservice;import java.util.Timer;import java.util.TimerTask;import com.example.testservice.ICat.Stub;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;public class AidlService extends Service{private CatBinder catBinder;Timer timer = new Timer();String[] colors = new String[]{"红色","黄色","黑色"};double[] weights = new double[]{2.3,3.1,1.58};private String color;private double weight;@Overridepublic IBinder onBind(Intent intent) {/* * 返回catBinder对象 * 在绑定本地Service的情况下,该catBinder对象会直接传给客户端的 * ServiceConnection对象的onServiceConnected方法的第二个参数; * 在绑定远程Service的情况下,只将catBinder对象的代理传给客户端的 * ServiceConnection对象的onServiceConnected方法的第二个参数; */return catBinder;}//继承Stub,也就是实现了ICat接口,并实现了IBinder接口public class CatBinder extends Stub{@Overridepublic String getColor() throws RemoteException {// TODO Auto-generated method stubreturn color;}@Overridepublic double getWeight() throws RemoteException {// TODO Auto-generated method stubreturn weight;}}@Overridepublic void onCreate() {super.onCreate();catBinder = new CatBinder();timer.schedule(new TimerTask() {@Overridepublic void run() {int rand = (int)(Math.random() * 3);color = colors[rand];weight = weights[rand];System.out.println("---------" + rand);}}, 0, 800);}}

(4)在AndroidMainfest.xml文件中配置该Service

        <service android:name=".AidlService">            <intent-filter>                <action android:name="com.example.testservice.action.AIDL_SERVICE"/>            </intent-filter>        </service>

(5)客户端访问AIDL Service

上面说过AIDL是定义在两个进程之间通信的一个接口,既然是一个通信协议,客户端同样需要前面定义的AIDL接口,所以第一步就是将AIDL文件复制到客户端应用中。

package com.example.testservice;import android.app.Activity;import android.app.Service;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.IBinder;import android.os.RemoteException;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;public class AidlClient extends Activity{private ICat catService;private Button get;EditText color, weight;private ServiceConnection conn = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {//获取远程Service的onBind方法返回的对象的代理catService = ICat.Stub.asInterface(service);}};protected void onCreate(android.os.Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);get = (Button)findViewById(R.id.get);color = (EditText)findViewById(R.id.color);weight = (EditText)findViewById(R.id.weight);//创建所需绑定的Service的IntentIntent intent = new Intent();intent.setAction("com.example.testservice.action.AIDL_SERVICE");bindService(intent, conn, Service.BIND_AUTO_CREATE);get.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {try {color.setText(catService.getColor());weight.setText(catService.getWeight() + "");} catch (RemoteException e) {e.printStackTrace();}}});};@Overrideprotected void onDestroy() {super.onDestroy();//解除绑定this.unbindService(conn);}}


下一篇将介绍如何在进程之间传递复杂数据




更多相关文章

  1. QtAndroid详解(3):startActivity实战Android拍照功能
  2. Android代码内存优化建议-Android资源篇
  3. android 中 Message详解
  4. Android类库常用类型解析
  5. Drawable Mutations(Android(安卓)Drawable 深入分析)
  6. android 中 application 的使用
  7. 通过对inflate与 findViewById 方法的探究深度了解一下Android
  8. Android输入子系统之启动过程分析
  9. android中Webview与javascript的交互(互相调用)

随机推荐

  1. sql 普通行列转换
  2. SQL Server的复制功能
  3. Oracle 10g各个帐号的访问权限、登录路径
  4. SQL Server 更改DB的Collation
  5. SQL Server约束增强的两点建议
  6. 存储过程解密(破解函数,过程,触发器,视图
  7. MSSQL SERVER中的BETWEEN AND的使用
  8. sql 数据库还原图文教程
  9. sql server中的decimal或者numeric的精度
  10. SQL 时间类型的模糊查询