Chinaunix首页 | 论坛 | 博客
  • 博客访问: 405341
  • 博文数量: 78
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 940
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-25 09:39
文章分类

全部博文(78)

文章存档

2016年(7)

2015年(1)

2014年(35)

2013年(35)

我的朋友

分类: Android平台

2014-11-19 16:39:47

Android Interface definition language(AIDL) 是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口。
    对于Service组件而言,它只有在绑定模式下才可以与客户端进行时交互。但是对于绑定服务传递数据,只局限于本地服务,无法使用服务进行跨进程间的交互。如果需要用到跨进程交互的话,需要用到一个新的技术——AIDL。



具体使用步骤:androidsdk/docs/guide/components/aidl.html

1、 创建aidl文件,aidl文件定义:写法跟java代码类似,但是这里有一点值得注意的就是它可以引用其它aidl文件中定义的接口,但是不能够引用你的java类文件中定义的接口。保存在src/目录,Service宿主和任何绑定这个服务的应用都需要。

点击(此处)折叠或打开

  1. private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
  2.     public int getPid(){
  3.         return Process.myPid();
  4.     }
  5.     public void basicTypes(int anInt, long aLong, boolean aBoolean,
  6.         float aFloat, double aDouble, String aString) {
  7.         // Does nothing
  8.     }
  9. };


注:AIDL默认情况下只能传递基本类型、String、List、Map、CharSequence。若需要传递其他复杂类型的对象,需要import对象的包名, 定义数据接口的AIDL文件中,使用parcelable关键字,在其数据实现类中实现Parcelable接口,并实现对应的方法。

2、  编译aidl文件,若是在eclipse中开发,adt插件会像资源文件一样把aidl文件编译成java代码生成在gen文件夹下,不用手动去编译。

3、  实现我们定义aidl接口中的内部抽象类Stub,Stub类继承了Binder,并继承我们在aidl文件中定义的接口,我们需要实现接口方法。注意Stub对象是在被调用端进程,也就是服务端进程,至此,完成aidl服务端的编码。

点击(此处)折叠或打开

  1. public class RemoteService extends Service {
  2.     @Override
  3.     public void onCreate() {
  4.         super.onCreate();
  5.     }

  6.     @Override
  7.     public IBinder onBind(Intent intent) {
  8.         // Return the interface
  9.         return mBinder;
  10.     }

  11.     private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
  12.         public int getPid(){
  13.             return Process.myPid();
  14.         }
  15.         public void basicTypes(int anInt, long aLong, boolean aBoolean,
  16.             float aFloat, double aDouble, String aString) {
  17.             // Does nothing
  18.         }
  19.     };
  20. }


4、  客户端如何调用服务端得aidl描述的接口对象,通过实现Service.onBind(Intent)方法,该方法会返回一个IBinder对象到客户端,其实它就是用来在客户端绑定service时接收service返回的IBinder对象的。注意在客户端需要存一个服务端实现了的aidl接口描述文件,但是客户端只是使用该aidl接口,不需要实现它的Stub类,获取服务端得aidl对象后mService = AIDLService.Stub.asInterface(service);就可以在客户端使用它了,对mService对象方法的调用不是在客户端执行,而是在服务端执行。

点击(此处)折叠或打开

  1. IRemoteService mIRemoteService;
  2. private ServiceConnection mConnection = new ServiceConnection() {
  3.     // Called when the connection with the service is established
  4.     public void onServiceConnected(ComponentName className, IBinder service) {
  5.         // Following the example above for an AIDL interface,
  6.         // this gets an instance of the IRemoteInterface, which we can use to call on the service
  7.         mIRemoteService = IRemoteService.Stub.asInterface(service);
  8.     }

  9.     // Called when the connection with the service disconnects unexpectedly
  10.     public void onServiceDisconnected(ComponentName className) {
  11.         Log.e(TAG, "Service has unexpectedly disconnected");
  12.         mIRemoteService = null;
  13.     }
  14. };


阅读(1320) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~