首页 > 代码库 > AIDL学习

AIDL学习

AIDL学习前知识

  AIDL:Android Interface Definition Language,即Android接口定义语言

  AIDL使用情景:Android中不同的进程之间不能直接通信,相互调用接口,实现数据的共享。此时,便能用AIDL来实现这中需求。

  Android使用Binder来实现进程间通信,Binder有点像一架桥梁,链接两个不同的进程:

  

  Binder能够携带processA的请求信息,告知processB需要调用processB的哪个接口,并返回processA所需要的接口引用。这个过程就像是本地请求服务器的数据操作一样,因此一般称processA为客户端,processB为服务端。

  AIDL做的工作就是给开发者提供一种固定的请求服务的代码格式,是一种写法,具体如何调用processB中的接口隐藏在简单格式的后面,由Android这一整套Binder机制来完成,无需开发者去操心,当然Binder机制还是可以学习的,这里不细说。

 

AIDL具体用法

  现在我们来尝试用AIDL来实现不同包之间的进程通信。

  1、由图我们可以看到,服务端我们写了一个AidlService的包,客户端我们新建了一个Test用来测试,我们需要在Test中调用AidlService中的MyService中的service,目标就是里面的count数据;

  

  

  2、首先我们需要把AidlService中的MyService的count通过一种方法包装出去,让所有的进程都能够调用。具体做法是新建一个AIDL文件,如上图所示,注意文件的后缀名是aidl:IMyService.aidl

  AIDL文件的写法很简单:

  

  里面申明了一个接口,接口是要拿到count数据。

  此时系统会自动在gen根目录下生成已个java文件:IMyService.java,这个正是AIDL有意思的地方,通过简单的AIDL文件申明,Binder机制中重要的调用关系不需要自己写,因为这是一套广泛使用的机制,所有Google把这个抽象出来了,便于开发者实现进程间调用,当然实现这个也可以完全自己去写接口代码,只是会降低代码耦合度。

  我们看看IMyService.java是怎么生成的:

  

  我们可以看到除了getCount()方法,还多了一个stub的抽象类,这个类正是申请Binder用的,继承了Binder类,绝大多数地方都没有修改。我们可以通过stub类,来创建Binder对象,借由这个对象来实现进程间通信。

  3、做完这个操作后,我们就可以在MyService中申明IMyService对象,获取Binder对象,实现getCount()方法。注意到Service自带的onBind方法,就是这个方法能够给客户端绑定service。

  

  4、到此服务端已经搭建完成,再来看客户端的调用规则。

  客户端需要和服务端一样,新建一个AIDL文件,和服务端一模一样,注意包名也需要一样,如此也会自动生成一个IMyService.java,且和AidlService中的一样。调用的时候,拿到ServiceConnection的一个对象,在onServiceConnectioned()中通过IMyService拿到接口实例,用这个connection设置intent,绑定service即可,

  

   之后便可以用intent直接调用AidlService中MyService中的getCount()方法了,注意的是远程调用需要加一个try-catch来防止远程调用exception。

  

 

 

 

 

 

 

AIDL学习