概述:
AIDL 意思即 Android Interface Definition Language,翻译过来就是Android接口定义语言,是用于定义服务器和客户端通信接口的一种描述语言,可以拿来生成用于IPC的代码。从某种意义上说AIDL其实是一个模板,因为在使用过程中,实际起作用的并不是AIDL文件,而是据此而生成的一个Interface的实例代码,AIDL其实是为了避免我们重复编写代码而出现的一个模板。AIDL目的就是为了实现进程间通信。
AIDL基本语法:
1、AIDL文件以 .aidl 为后缀名
2、AIDL支持的数据类型分为如下几种:
- 八种基本数据类型:byte、char、short、int、long、float、double、boolean
String,CharSequence
- 实现了Parcelable接口的数据类型
- List 类型。List承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象
- Map类型。Map承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象
3、AIDL文件可以分为两类。一类用来声明实现了Parcelable接口的数据类型,以供其他AIDL文件使用那些非默认支持的数据类型。还有一类是用来定义接口方法,声明要暴露哪些接口给客户端调用,定向Tag就是用来标注这些方法的参数值
Android使用AIDL
1.步骤
(1)在Eclipse Android工程的Java包目录中建立一个扩展名为A.aidl的文件,并写下需要的接口。如果aidl文件的内容是正确的,ADT会在gen目录下自动生成一个A.Java接口文件。
(2)建立一个服务类(Service的子类)。并在创建的服务类中创建一个内部类,实现由aidl文件生成的Java接口。
(3)在服务类的onBind方法返回时,将实现aidl接口的内部类对象返回出去。
(4)在AndroidManifest.xml文件中配置AIDL服务,尤其要注意的是,标签中android:name的属性值就是客户端要引用该服务的ID,也就是Intent类的参数值。
2、具体操作
(1)创建文件InterfaceService.aidl
package my.wyl; interface InterfaceService{ //只有一个接口 String getPrice(); }
(2)创建服务类及实现内部类MyService.java
public class MyService extends Service { @Override public IBinder onBind(Intent arg0) { // 把内部类的对象返回给客户端使用 return new MyServiceImpl(); } // 创建一个继承自InterfaceService.Stub的内部类 public class MyServiceImpl extends InterfaceService.Stub { // 必须实现AIDL文件中的接口 public String getPrice() throws RemoteException { return null; } } }
注意,在自定义的MyService中,onBind方法必须返回MyServiceImpl类的对象实例,否则客户端无法获得服务对象。
(3)在AndroidManifest.xml中配置MyService
<service android:name=".MyService" >
<intent-filter>
<action android:name="my.wyl.InterfaceService" />
</intent-filter>
</service>
上面的" my.wyl.InterfaceService "是客户端用于访问AIDL服务的ID。
3:本地客户端的使用方法:
(1) 新建一个Android目录,并将刚才远程服务端自动生成的gen目录下面的InterfaceService.java文件连同包目录一起复制到客户端工程的src目录中。
(2) 调用AIDL服务要先绑定服务,然后才能获得服务对象。
public class AIDLClientActivity extends Activity { // 远程服务端的对象 InterfaceService interfaceService; private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName name, IBinder service) { // 绑定成功,得到远程服务端的对象,目标完成!!! interfaceService = InterfaceService.Stub.asInterface(service); } public void onServiceDisconnected(ComponentName name) { // 解除绑定 interfaceService = null; } };
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 绑定远程服务端服务 Intent serviceIntent = new Intent("my.wyl.InterfaceService"); bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE); Log.i(“TAG”, interfaceService.getPrice()) } }
4.使用AIDL小结
服务端方面:将需要开放的接口抽象到aidl文件中,然后在自己的内部类中对接口进行实现,并在自己被绑定的时候把内部类对象返回给客户端。
客户端方面:当我们需要远程某个Service时,就像在绑定本地的Service一样去bindService,然后在绑定成功的回调函数中(也就是onServiceConnected方法)得到一个Ibinder对象(比如Service),这时调用InterfaceService.Stub.asInterface(service)这样的语句,就可以得到服务端开放的interface接口对象,此时客户端可以直接调用这个对象的方法,犹如直接调用远程的Service对象一般。
5.定向Tag
InOut 类型的表现形式是,服务端对数据的改变同时也同步到了客户端,因此可以说两者之间数据是双向流动的
In 类型的表现形式是:数据只能由客户端传向服务端,服务端对数据的修改不会影响到客户端
Out类型的表现形式是:数据只能由服务端传向客户端,即使客户端向方法接口传入了一个对象,该对象中的属性值也是为空的,即不包含任何数据,服务端获取到该对象后,对该对象的任何操作,就会同步到客户端这边