概述
AIDL是Android Interface Definition Language的缩写,在某种意义上讲,AIDL其实是一个模板,有规范和约束的作用。实际上起作用的是根据AIDL而生产的实例代码。
AIDL与Java语音的接口十分的相似,也它也有一些几点特点:
- AIDL支持的数据格式支持8大基本数据类型(byte、char、short、int、long、float、double、boolean,String,CharSequence),支持的空间数据结构有List和Map。
- 数据流向标记。in、out、inout。in 表示数据只能由客户端流向服务端, out 表示数据只能由服务端流向客户端,而 inout 则表示数据可在服务端与客户端之间双向流通。
- 手动导包。
 在Android中,跨进程通信采用的Binder机制,而基于Binder来实现跨进程的方式通常是采用AIDL和Massenger。
 两者的关系是:AIDL是基于Messenger,而Messenger是基于Binder的。
 关于更多关于Binder机制的知识可参看《IPC机制》
AIDL具体实现
在AS中添加.aidl文件:
- 首先定义服务接口,IMyAidlInterface.aidl: - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12- // IMyAidlInterface.aidl 
 package com.zhouk.soft.mystudio;
 //引用数据类型
 import com.zhouk.soft.mystudio.entity.TestAidlBean;
 interface IMyAidlInterface {
 String AIDL_Service();
 void addMyAidlBean(in TestAidlBean bean);//添加Bean到List里
 List<TestAidlBean> getList();//获取List
 }
- 定义引用类型,TestAidlBean.aidl: - 1 
 2
 3
 4- // TestAidlBean.aidl 
 package com.zhouk.soft.mystudio.entity;
 parcelable TestAidlBean;
注意,aidl引用数据类型必须与Java中对应的Bean相同包名
- AIDL文件添加完成后Make Project一下。会根据IMyAidlInterface.aidl来生成IMyAidlInterface.java文件。 - 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
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113- public interface IMyAidlInterface extends android.os.IInterface { 
 /**
 * Binder对象
 */
 public static abstract class Stub extends android.os.Binder implements com.zhouk.soft.mystudio.IMyAidlInterface {
 /**
 * Cast an IBinder object into an com.zhouk.soft.mystudio.IMyAidlInterface interface,
 * generating a proxy if needed.
 */
 public static com.zhouk.soft.mystudio.IMyAidlInterface asInterface(android.os.IBinder obj) {
 // ... ...
 return new com.zhouk.soft.mystudio.IMyAidlInterface.Stub.Proxy(obj);
 }
 
 public android.os.IBinder asBinder() {
 return this;
 }
 //收到Binder驱动通知后,Server 进程通过回调Binder对象onTransact()进行数据解包 & 调用目标方法
 
 public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
 switch (code) {
 case INTERFACE_TRANSACTION: {
 reply.writeString(DESCRIPTOR);
 return true;
 }
 case TRANSACTION_AIDL_Service: {
 data.enforceInterface(DESCRIPTOR);
 java.lang.String _result = this.AIDL_Service();
 reply.writeNoException();
 reply.writeString(_result);
 return true;
 }
 case TRANSACTION_addMyAidlBean: {
 data.enforceInterface(DESCRIPTOR);
 com.zhouk.soft.mystudio.entity.TestAidlBean _arg0;
 if ((0 != data.readInt())) {
 _arg0 = com.zhouk.soft.mystudio.entity.TestAidlBean.CREATOR.createFromParcel(data);
 } else {
 _arg0 = null;
 }
 this.addMyAidlBean(_arg0);
 reply.writeNoException();
 return true;
 }
 case TRANSACTION_getList: {
 data.enforceInterface(DESCRIPTOR);
 java.util.List<com.zhouk.soft.mystudio.entity.TestAidlBean> _result = this.getList();
 reply.writeNoException();
 reply.writeTypedList(_result);
 return true;
 }
 }
 //将结算结果返回 到Binder驱动
 return super.onTransact(code, data, reply, flags);
 }
 // 1. Binder驱动根据 代理对象 沿原路 将结果返回 并通知Client进程获取返回结果
 // 2. 通过代理对象 接收结果(之前被挂起的线程被唤醒)
 private static class Proxy implements com.zhouk.soft.mystudio.IMyAidlInterface {//mRemote.transact()
 private android.os.IBinder mRemote;
 Proxy(android.os.IBinder remote) {
 mRemote = remote;
 }
 
 public android.os.IBinder asBinder() {
 return mRemote;
 }
 public java.lang.String getInterfaceDescriptor() {
 return DESCRIPTOR;
 }
 
 public java.lang.String AIDL_Service() throws android.os.RemoteException {
 // ... ...
 mRemote.transact(Stub.TRANSACTION_AIDL_Service, _data, _reply, 0);
 _reply.readException();
 _result = _reply.readString();
 // ... ...
 return _result;
 }
 
 public void addMyAidlBean(com.zhouk.soft.mystudio.entity.TestAidlBean bean) throws android.os.RemoteException {
 // ... ...
 mRemote.transact(Stub.TRANSACTION_addMyAidlBean, _data, _reply, 0);
 _reply.readException();
 // ... ...
 }
 
 public java.util.List<com.zhouk.soft.mystudio.entity.TestAidlBean> getList() throws android.os.RemoteException {
 // ... ...
 mRemote.transact(Stub.TRANSACTION_getList, _data, _reply, 0);
 _reply.readException();
 _result = _reply.createTypedArrayList(com.zhouk.soft.mystudio.entity.TestAidlBean.CREATOR);
 // ... ...
 return _result;
 }
 }
 // ... ...
 }
 public java.lang.String AIDL_Service() throws android.os.RemoteException;
 public void addMyAidlBean(com.zhouk.soft.mystudio.entity.TestAidlBean bean) throws android.os.RemoteException;
 public java.util.List<com.zhouk.soft.mystudio.entity.TestAidlBean> getList() throws android.os.RemoteException;
 }
- 定义进程服务 - 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- /** 
 * Created by ZhouKang on 2018/4/14
 * 多进程,Server角色
 */
 public class TestServerService extends Service {
 private static final String TAG = "服务TestServerService";
 private List<TestAidlBean> listBean;
 
 public IBinder onBind(Intent intent) {
 Log.e(TAG, "已开启service进程服务");
 return myAidlInterface;
 }
 
 public boolean onUnbind(Intent intent) {
 return super.onUnbind(intent);
 }
 
 public void onCreate() {
 super.onCreate();
 listBean = new ArrayList<>();
 }
 IMyAidlInterface.Stub myAidlInterface = new IMyAidlInterface.Stub() {
 
 public String AIDL_Service() throws RemoteException {
 return "这是一条来自Service的消息";
 }
 
 public void addMyAidlBean(TestAidlBean bean) throws RemoteException {
 listBean.add(bean);
 Log.e(TAG, "已添加来自客户端的Bean");
 }
 
 public List<TestAidlBean> getList() throws RemoteException {
 return listBean;
 }
 };
 }
还要再AndroidManifest中注册一下,利用android:process为服务开启新的进程1
2
3
4
5
6
7
8<service
            android:name=".service.TestServerService"
            android:process=":remote">
            <intent-filter>
                <action android:name="com.zhouk.soft.mystudio.service.TestServerService"/>
                <!--<action android:name="scut.carson_ho.service_server.AIDL_Service1"/>-->
            </intent-filter>
        </service>
- 在应用主进程的活动中开启进程服务 - 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- private static final String TAG = "客户端TestClientActivity"; 
 private IMyAidlInterface ser;
 private ServiceConnection mServiceConnection = new ServiceConnection() {
 
 public void onServiceConnected(ComponentName name, IBinder service) {
 ser = IMyAidlInterface.Stub.asInterface(service);
 if (ser != null) {
 try {
 Log.e(TAG, ser.AIDL_Service());
 Toast.makeText(TestClientActivity.this, ser.AIDL_Service(), Toast.LENGTH_LONG).show();
 } catch (RemoteException e) {
 e.printStackTrace();
 }
 }
 }
 
 public void onServiceDisconnected(ComponentName name) {
 }
 };
 
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 Log.e(TAG, "开始连接其他进程的服务...");
 Intent intent = new Intent("com.zhouk.soft.mystudio.service.TestServerService");
 //需要通过setPackage()方法指定包名
 intent.setPackage(getPackageName());
 //绑定服务,传入intent和ServiceConnection对象
 boolean isS = bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
 Log.e(TAG, "是否连接成功:"+isS);
 findViewById(R.id.btn).setOnClickListener(v -> {//往服务进程中添加Bean数据
 try {
 ser.addMyAidlBean(new TestAidlBean(123456, "name1"));
 } catch (RemoteException e) {
 e.printStackTrace();
 }
 });
 findViewById(R.id.btn2).setOnClickListener(v -> {//获取服务进程中的List数据
 if (ser != null) {
 try {
 for (int i = 0; i < ser.getList().size(); i++) {
 Log.e(TAG, "列表数据" + i + ":--->" + ser.getList().get(i).getName());
 }
 } catch (RemoteException e) {
 e.printStackTrace();
 }
 }
 });
 }
- 结果 
 客户端: 
 服务端: 
 客户端: 
总结
主要介绍了AIDL基于C/S的实现操作。日常开发中使用多进程的场景并不多见,但在有些地方例如音视频开发中能起到十分关键的作用,掌握基础的多进程开发知识还是十分有必要的。