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标识即可,一般传包名;服务端在返回的时候同样将标识传回去;客户端在接收到消息后在判断标识即可;这样在服务端返回的时候就可以实现一对一或一对多的返回;