AIDL
官網定義
AIDL(Android 接口定義語言)與您可能使用過的其他 IDL 類似。 您可以利用它定義用戶端與服務使用程序間通信 (IPC) 進行互相通信時都認可的程式設計接口。 在 Android 上,一個程序通常無法通路另一個程序的記憶體。 盡管如此,程序需要将其對象分解成作業系統能夠識别的原語,并将對象編組成跨越邊界的對象。 編寫執行這一編組操作的代碼是一項繁瑣的工作,是以 Android 會使用 AIDL 來處理。
支援類型
Java基本資料類型(int,long,char,boolean,float,double等);
CharSequence,String
實作Parcelable的對象
List和Map(元素必須是以上支援的資料類型,生成方法使用List和Map,接受端實際類型為ArrayList和HashMap)
實作
實作Parcelable實體
要傳遞的實體類UserBean
public class UserBean implements Parcelable {
private String name;
private int age;
private String address;
public UserBean() {
}
public UserBean(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
public String getName() {
return name;
public void setName(String name) {
public int getAge() {
return age;
public void setAge(int age) {
public String getAddress() {
return address;
public void setAddress(String address) {
protected UserBean(Parcel in) {
name = in.readString();
age = in.readInt();
address = in.readString();
public static final Creator<UserBean> CREATOR = new Creator<UserBean>() {
@Override
public UserBean createFromParcel(Parcel in) {
return new UserBean(in);
public UserBean[] newArray(int size) {
return new UserBean[size];
};
public int describeContents() {
return 0;
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
dest.writeString(address);
/**
* 需要手動添加,Android Studio沒法直接生成
*/
public void readFromParcel(Parcel reply) {
name = reply.readString();
age = reply.readInt();
address = reply.readString();
public String toString() {
return "UserBean{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
注: Android Studio中實作Parcelable設定完屬性就能快速生成必要的代碼,但是readFromParcel方法需要手動實作,否則無法編譯通過會報錯
Process 'command 'D:\software\android\sdk\build-tools\28.0.3\aidl.exe'' finished with non-zero exit value 1
AIDL檔案
映射對象
// UserBean.aidl
package com.sjl.exercise.bean;
// Declare any non-default types here with import statements
parcelable UserBean;
接口aidl
注:
import聲明任何非預設類型(例 UserBean)
方法中除了基本資料類型,其他類型的需要标上方向類型(in,out,inout)
// ICustomAidlInterface.aidl
package com.sjl.exercise;
import com.sjl.exercise.bean.UserBean;
interface ICustomAidlInterface {
String getCurrentTime();
void insertUser(in UserBean userBean);
List<UserBean> getUsers();
void clearUser();
定義完成後Make Project一下等待建構完成
服務端
建立遠端服務
public class RemoteService extends Service {
private static final String TAG = "RemoteService";
private List<UserBean> list = new ArrayList<>();
ICustomAidlInterface.Stub stub = new ICustomAidlInterface.Stub() {
public String getCurrentTime() throws RemoteException {
return new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date());
public void insertUser(UserBean userBean) throws RemoteException {
list.add(userBean);
public List<UserBean> getUsers() throws RemoteException {
return list;
public void clearUser() throws RemoteException {
list.clear();
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate");
Toast.makeText(this, "遠端服務onCreate", Toast.LENGTH_SHORT).show();
* 傳回IBinder用于通信
* @param intent
* @return
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind");
Toast.makeText(this, "遠端服務onBind", Toast.LENGTH_SHORT).show();
return stub;
public boolean onUnbind(Intent intent) {
Log.i(TAG, "onUnbind");
Toast.makeText(this, "遠端服務onUnbind", Toast.LENGTH_SHORT).show();
return super.onUnbind(intent);
public void onDestroy() {
Log.i(TAG, "onDestroy");
Toast.makeText(this, "遠端服務onDestroy", Toast.LENGTH_SHORT).show();
super.onDestroy();
AndroidManifest.xml配置服務,定義Action用于隐式喚醒
<service
android:name=".module.service.remote.RemoteService"
android:enabled="true"
android:exported="true"
android:process=":remote">
<intent-filter>
<action android:name="com.sjl.aidl.remote" />
</intent-filter>
</service>
用戶端
拷貝服務端的aidl檔案及自定義的UserBean對象放到用戶端的中,路徑需要與服務端保持一緻
綁定服務
Intent intent = new Intent();
//AndroidManifest.xml中定義的伺服器端Action
intent.setAction("com.sjl.aidl.remote");
//5.0後無法通過隐式Intent綁定遠端Service,需設定包名
intent.setPackage("com.sjl.exercise");
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
擷取到AIDL接口
private ICustomAidlInterface iCustomAidlInterface;
private ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
iCustomAidlInterface = ICustomAidlInterface.Stub.asInterface(service);
Log.i(TAG, "onServiceConnected");
Toast.makeText(MainActivity.this, "service connected", Toast.LENGTH_SHORT).show();
public void onServiceDisconnected(ComponentName name) {
Log.i(TAG, "onServiceDisconnected");
iCustomAidlInterface = null;
調用AIDL接口
iCustomAidlInterface.getCurrentTime();
UserBean userBean = new UserBean();
userBean.setName("name" + cnt);
userBean.setAddress("address" + cnt);
userBean.setAge(cnt);
iCustomAidlInterface.insertUser(userBean);
iCustomAidlInterface.getUsers();
iCustomAidlInterface.clearUser();
UserBean
---------------------