安卓开发AIDL进程间通信实现应用间双向通信

1、编写aidl文件

如果要实现应用间的双向通信,就至少要编写两个aidl文件;一个用于发送,一个用于接收;且在发送的aidl文件中,实现一个callback方法,参数持有另一个aidl文件对象;
代码示例:

interface IJsonProtocolInterface {
    void request(String jsonData);
    void regCallBack(ICallBackInterface iCallBack);
    void unRegCallBack(ICallBackInterface iCallBack);
}
interface ICallBackInterface {
    void onResult(String result);
}

2、重新build项目,生成对应的java文件

此步需要注意的是,需要保证客户端和服务端拥有一样的aidl文件和路径;建议以sdk的方式去集成到客户端和服务端;java文件中,需要重点注意的是里面的Stub类;此类是实现通信的关键;当前其他生成类也很重要,感兴趣的可以去研究一下原理,此处只教大家怎么使用,便于快速上手;

3、服务端实现

新建一个服务,用于客户端绑定;然后新建实现类继承aidl转java类中的stub内部代理类;代码如下:

public static class MyIBind extends IJsonProtocolInterface.Stub {

        @Override
        public void request(String s) throws RemoteException {
            Log.d(TAG,"request ");
        }

        @Override
        public void regCallBack(ICallBackInterface iCallBackInterface) throws RemoteException {
            Log.d(TAG,"regCallBack ");
        }

        @Override
        public void unRegCallBack(ICallBackInterface iCallBackInterface) throws RemoteException {
            Log.d(TAG,"unRegCallBack ");
        }
    }

4、客户端实现

客户端需要做绑定服务的操作;因为是双向通信,所以在绑定连接后还要做设置回调的一步;
代码如下:

private void startBinding() {
        isInBinding = true;
        bindCount++;
        Intent intent = new Intent();
        intent.setAction(ProtocolConstant.ACTION_JSON_PROTOCOL_SERVICE);
        intent.setPackage(mBindPackageName);
        isBind = context.bindService(intent, connection, Service.BIND_AUTO_CREATE);
        Log.d(TAG, "isBind = " + this.isBind + "  bindCount: " + bindCount);
        if (!isBind) {
            if (bindCount <= maxReconnectTime) {
                handler.postDelayed(mReconnectRunnable, maxReconnectDuration);
            } else {
                for (IJsonProtocolReceive iJsonProtocolReceive : iJsonProtocolReceives) {
                    if (iJsonProtocolReceive != null) {
                        iJsonProtocolReceive.received(null, -2);
                    }
                }
                isInBinding = false;
                Log.d(TAG, "bindCount = " + bindCount + " isBind = " + isBind);
                bindCount = 0;
            }
        }
    }
private final ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.d(TAG, "onServiceConnected");
            //连接成功后,获取到aidl文件的代理类对象
            iJsonProtocolInterface = IJsonProtocolInterface.Stub.asInterface(iBinder);
            if (null == iJsonProtocolInterface) {
                Log.d(TAG, "registerCallback protocolAidlInterface is null");
                return;
            }
            bindCount = 0;
            isInBinding = false;
            Log.d(TAG, "registerCallback");
            try {
            	//此处设置回调
                iJsonProtocolInterface.regCallBack(iCallBackInterface);
            } catch (RemoteException e) {
                e.printStackTrace();
                Log.d(TAG, "setCallBack RemoteException");
            }
            try {
            //此处设置死亡回调
                iBinder.linkToDeath(mDeathRecipient, 0);
            } catch (RemoteException e) {
                e.printStackTrace();
                Log.d(TAG, "linkToDeath RemoteException");
            }
            for (IJsonProtocolReceive iJsonProtocolReceive : iJsonProtocolReceives) {
                if (iJsonProtocolReceive != null) {
                    iJsonProtocolReceive.notifyState();
                }
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.d(TAG, "onServiceDisconnected");
            BlJsonProtocolManager.this.iJsonProtocolInterface = null;
            isBind = false;
            for (IJsonProtocolReceive iJsonProtocolReceive : iJsonProtocolReceives) {
                if (iJsonProtocolReceive != null) {
                    iJsonProtocolReceive.received(null, -1);
                }
            }
            bindService(context, mBindPackageName);
        }

        @Override
        public void onBindingDied(ComponentName name) {
            if (isBind) {
                resetConnectionFlag();
                bindService(context, mBindPackageName);
            }
        }
    };

5、实现通信

完成以上步骤后,即可实现客户端和服务端之间的双向通信;具体如下:
1、客户端通过iJsonProtocolInterface代理类调用aidl文件中的函数传递信息给到服务端处理;
2、服务端通过客户端注册回调传过来的iCallBackInterface代理类中的方法传递信息给到客户端处理;

6、多客户端绑定的实现

aidl是支持多客户端的绑定的;问题是服务端在接收到客户端的信息时,不知道是哪个客户端传过来的,这样的话就无法实现单对单的返回;其实可以在客户端传过来的参数中加上一个flag标识即可,一般传包名;服务端在返回的时候同样将标识传回去;客户端在接收到消息后在判断标识即可;这样在服务端返回的时候就可以实现一对一或一对多的返回;

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值