Android 接口定义语言 AIDL(Android Interface Definition Language)与其他已有的 IDL 很类似。 客户端和服务端可以通过由它定义的编程接口来达成共识,以便通过进程间通讯(IPC)完成相互通讯。 在 Android 系统中,通常一个进程不允许直接访问另一个进程的内存。 因此为了能够实现对话,进程需要把对象分解为操作系统可以识别的原生数据,在跨越进程边界后再组装起来。 实现组装的代码非常枯燥无趣,因此 Android 通过 AIDL 可有助于完成这一过程。
仅当允许其他应用程序通过 IPC 方式访问服务,并且服务需要多线程运行时,才必须用到 AIDL。
AIDL实现方法:
1.创建.aidl文件
package com.example.aidl;
interface DataService{
int getData(String name);
}
注意,函数前面不需要public修饰符。
在编译应用程序时,会在gen/目录下生成DataService接口文件
2.服务端实现接口并向客户端公布
.aidl文件被自动生成.java接口文件。它包含一个静态子类Stub,该子类扩展了Binder类,且实现父接口。
所以,我们应该扩展Stub,并实现由.aidl文件继承的方法。
private Binder binder = new DataService.Stub() {
@Override
public int getData(String name) throws RemoteException {
if(name.equals("hello")){
return 10000;
}
return -1;
}
};
然后在onBind方法中返回该接口的实例,向客户端公布接口
public IBinder onBind(Intent intent) {
return binder;
}
最后在AndroidManifest.xml注册service
<service android:name="ServerService">
<intent-filter>
<action android:name="com.example.aidl.DataService"/>
</intent-filter>
</service>
这里action必须要,不然到后面会报错
server端布局文件就一个button用于启动service
server端代码结构
接下来是客户端
客户端布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.aidlclient.MainActivity" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="69dp"
android:text="绑定服务" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/button1"
android:layout_below="@+id/button1"
android:layout_marginTop="52dp"
android:text="调用服务" />
</RelativeLayout>
button1的功能
button1 = (Button)findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(DataService.class.getName());
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
});
button2后面再提
3.客户端获取接口实例
为了让客户端有权限访问接口类,客户端必须拥有一份.aidl文件的拷贝,用于生成供客户端访问AIDL方法的Binder接口。
在接收到回调方法onServiceConnected中的IBinder时,客户端必须调用DataService.Stub.asInterface(service)来把返回的参数转换为DataService类型。之后就可以使用该接口和服务端通信了。(先启动server,再启动client)
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
dataService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
dataService = DataService.Stub.asInterface(service);
}
};
button2功能
button2 = (Button)findViewById(R.id.button2);
button2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
int result = dataService.getData("hello");
Log.i("test", result+"----------");
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
更多详情可以参考
http://blog.csdn.net/sun971782067/article/details/49494577
http://www.cnblogs.com/popapa/p/android_aidl.html