AIDL进程间通信

  • 简介
  • 项目结构
  • 服务端
  • 客户端

简介

aidl:android interface definition language(安卓接口定义语言),主要用于安卓系统中的跨进程通信。

项目结构

aidlserver:服务端,包含aidl、service、序列化的实体类。
aidlclient:客户端,包含aidl、实体类、绑定service代码。

服务端

1. 创建aidl文件。
在android studio创建一个服务端(注:本博客中所有所说的服务端和客户端都是相对的,因为安卓系统中的每一个项目都可以充当服务端和客户端,只是为了说明aidl才这么称呼它们)项目,本例中项目名称为aidlserver。
首先创建aidl文件:在项目名称右键—>New—>AIDL—>AIDL File,Android Studio可以自动创建aidl目录和文件。
2. 定义ICalculator接口。
写一个方法int add(int a, int b),该方法计算两个参数的和作为返回值,写完该aidl后点击Sync按钮同步一下工程,可以自动生成ICalculator.java文件。

interface ICalculator {
    /**
     * 加法计算
     */
    int add(int a, int b);
}

3. 创建服务。
创建RemoteServer,根据ICalculator.java的Stub方法生成IBinder对象,在重写的add方法中写这个方法的逻辑。
ICalculator.java中有一个Stub抽象类,这个抽象类继承自Binder,实现了ICalculator接口,创建这个抽象类的对象向上转型为IBinder对象,在创建的抽象类中重写add方法,这个方法里就是操作客户端传来的两个参数的逻辑,本例中是计算它们的和然后返回。

private IBinder iBinder = new ICalculator.Stub() {
        @Override
        public int add(int a, int b) throws RemoteException {
            return a + b;
        }
    };

重写service的onBind方法,在该方法中返回上一步生成的iBinder。

@Override
    public IBinder onBind(Intent intent) {
        //绑定service后返回ibinder
        Log.d(TAG, "RemoteServer onBind");
        return iBinder;
    }

客户端

1. 创建aidl文件
在android studio创建一个客户端项目,本例中项目名称为aidlclient。
因为客户端的aidl文件包名需要与服务端一致,所以与服务端创建aidl文件不同的是,客户端需要先创建aidl目录,在该目录下创建服务端包名,然后创建aidl文件,该文件内容与服务端完全一致。在创建完成该文件后,同样需要同步工程。
2. 创建ServiceConnection
在activity中绑定service,在绑定成功的onServiceConnected回调中创建ICalculator对象。
ICalculator.java中有一个DESCRIPTOR字段,该字段就是创建的aidl包名+文件名,根据该字段判断IBinder参数是否是DESCRIPTOR对应的接口的实例,是则返回强转的对象,否则返回代理类。

private ICalculator iCalculator;
private ServiceConnection serviceConnection = new                      ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "serviceConnection onServiceConnected");
            iCalculator = ICalculator.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "serviceConnection onServiceDisconnected");
            iCalculator = null;
        }
    };

3. 绑定service

Intent intent = new Intent();
        intent.setComponent(new ComponentName("cn.qiiyue.aidlserver", "cn.qiiyue.aidlserver.RemoteServer"));
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

4. 接收结果
在此处调用add方法,服务端的逻辑进行计算,返回结果。

int result = iCalculator.add(1, 2);
Log.d(TAG, "result: " + result);