[Android 学习笔记]AIDL
Oct 10, 2013
简略地翻译一遍谷歌的教程,加深自己的理解。。。
AIDL(Android Interface Definition Language)用于来自不同应用的客户端访问service进行进程数据交换(IPC)
#创建一个AIDL接口的步骤:
- 创建一个.aidl文件
- 实现接口
暴露接口给客户端
##创建一个.aidl文件
.aidl文件的语法使用的是java语法,但做了一些限制,每一个.aidl文件都只定义一个接口,并且只能声明接口和抽象方法
.aidl文件支持以下数据类型:- 所有的java基本类型(如int,long,byte,double,char,boolean等)
- String
- CharSequence
- List
List中的元素数据类型必须是以下三种之一- List集合支持的数据类型
- 其他AIDL生成的接口
- 实现了Parcelable接口
- Map
Map中的元素数据类型要求同上面的List.
上面未列出来的类型在使用的时候必须使用import声明导入,即使这个类和.aidl文件在同一个包下。
在定义一个service接口的时候需要注意的是:- 方法可以没有参数,返回值可有可无
- 所有非基本数据类型的参数都需要指示出数据离开的方向(in/out/inout)
- 所有.aidl文件中的注释都包含在生成的IBinder接口中(声明在import和package语句之前的注释除外)
- 只能声明抽象方法,不能定义静态常量
我创建了如下的MyAidl.aidl文件1
2
3
4
5
6
7
8
9package com.diaoslin.androidlearn.service;
/**
* Created by lin on 13-10-10.
*/
interface MyAidl {
void showNotification();
void cancelNotification();
}
##实现接口
当建立好.aidl文件后,Android SDK Tool会自动生成相应的.java文件,使用Android Studio需要在build.gradle文件中指定AIDL目录,如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14android {
compileSdkVersion 17
buildToolsVersion "18.1.0"
defaultConfig {
minSdkVersion 7
targetSdkVersion 16
}
sourceSets {
main {
aidl.srcDirs = ['src/main/java']
}
}
}
生成的java接口类中,包含所有在.aidl文件中声明的方法,还有一个Stub抽象子类。
要实现.aidl文件中声明的接口,需要继承这个Stub子类,并且实现所有.aidl中声明的方法,1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24MyAidl.Stub mBinder = new MyAidl.Stub() {
public void showNotification(){
Log.d("mBinder", "showNotification");
Intent i = new Intent(AidlService.this, AidlActivity.class);
PendingIntent pi = PendingIntent.getActivity(AidlService.this, 0, i, 0);
Notification notification = new Notification.Builder(AidlService.this)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_launcher)
.setWhen(System.currentTimeMillis())
.setContentTitle("标题")
.setTicker("显示通知成功")
.setContentIntent(pi)
.setContentText("消息内容")
.build();
mNotificationManager.notify(NOTIFICATION_ID, notification);
}
public void cancelNotification() throws RemoteException {
mNotificationManager.cancel(NOTIFICATION_ID);
}
};- ##暴露接口给客户端
在service的onBind()方法中返回.Stub对象,在客户端中,在ServiceConnect对象的onServiceConnected()方法中
调用MyAidl.Stub.asInterface(service)
这个Sub子类冲还包含一个比较重要的方法:asInterface()
这个方法通常在ServiceConnecttion对象的onServiceConnected()方法中调用,返回一个MyAidl.Stub对象1
2
3
4
5
6
7
8
9
10
11
12
13ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
mMyAidl = MyAidl.Stub.asInterface(service);
Log.d("mConnection", "onServiceConnected");
}
public void onServiceDisconnected(ComponentName name) {
mMyAidl = null;
Log.d("mConnection", "onServiceDisconnected");
}
};
当客户端调用bindService()绑定Service后,可以通过ServiceConnection对象的onServiceConnected()方法获得MyAidl.Stub对象
#在IPC中传递对象
如果需要在进程之间通过IPC接口传递对象,那么这个对象的class必须实现了Parcelable接口
#参考资料: