我们都知道在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远程访问的功能。

Android菜鸟的成长笔记(21)——跨进程调用Service_第1张图片

自动生成的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. fanfou(饭否) android客户端 代码学习1
  2. Android腾讯微薄客户端开发十四:首页menu菜单
  3. android mina 客户端无法接收信息的原因
  4. android webview 添加内置对象
  5. Android App怎样调用 Frameworks Bluetooth接口
  6. Android客户端自动更新代码
  7. android 客户端 smtp 协议发送数据

随机推荐

  1. Android(安卓)对话框
  2. android软键盘隐藏总结
  3. android4.2上获取应用程序大小的变更点
  4. Android(安卓)解决Handler在运行时加载报
  5. Android中MediaButtonReceiver广播监听器
  6. Android中各种onTouch事件
  7. Android修炼之道—时间测量
  8. Get the Android(安卓)SDK---获取Android
  9. php直播源码安卓自定义Dialog设置自动消
  10. Android(安卓)onMeasure、Measure、measu