先回顾一下aidl的使用方法,可以参考上篇介绍的AIDL怎么用,链接如下:
https://www.jianshu.com/p/86d7c81eb6f8
Server端:
1、创建aidl接口文件以及数据(Parcelable)文件;
2、创建service文件,在AndroidManifest.xml中声明action;
3、在service文件中添加IxxxInterface.Stub,以及对应aidl接口实现,例如:
private IMediaShareInterface.StubmIMediaShareMgr = new IMediaShareInterface.Stub() {
@Override
public void onMediaSharing(MediaDatadata) throws RemoteException {
}
};
Client端:
1、 创建和server端相应的aidl文件(可以直接从server端复制一份);
2、 在Activity中添加ServiceConnection,在onStart中添加bindService,在onStop中添加unbindService,例如:
private ServiceConnection mServiceConnection =new ServiceConnection() {
@Override
public voidonServiceConnected(ComponentName componentName, IBinder service) {
}
@Override
public voidonServiceDisconnected(ComponentName componentName) {
}
};
在项目开发过程中,有时候会碰到以下类似的场景:在两个app建立了Binder通信后,Client端需要Server端的某个状态,才能触发将数据传给Server端。但是Client端并没有接口可以回调来处理记录这个状态。这个时候就需要增加一个回调接口,来实现以上功能。框架流程大概如下:
图11、创建一个aidl接口,增加需要回调的接口,例如:
//IVoipTransferInterface.aidl
package com.suning.voicetransfer;
import com.suning.voicetransfer.IVoiceTransferListener;
import com.suning.voicetransfer.VoiceData;
interface IVoiceTransferInterface {
void setVoiceTransferListener(IVoiceTransferListenerlistener);
void onVoiceTransfer(in VoiceDatadata);
}
2、在原有aidl接口基础上再新增一个接口,再把这个aidl接口类作为参数,这样Client端在收到onServiceConnected时,就可以将接口设置进来。例如:
privateboolean mIsSendVoip;
private IVoiceTransferInterface mIVoiceTransferMgr;
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentNamecomponentName, IBinder service) {
if (service != null) {
try {
service.linkToDeath(mDeathRecipient,0);
} catch (RemoteException e) {
e.printStackTrace();
}
}
mIsSendVoip = false;
mIVoiceTransferMgr =IVoiceTransferInterface.Stub.asInterface(service);
if (mIVoiceTransferMgr != null) {
try {
mIVoiceTransferMgr.setVoiceTransferListener(mVoiceTransferListener);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
@Override
public void onServiceDisconnected(ComponentNamecomponentName) {
}
};
其中IVoiceTransferInterface就是新增的接口类 ,在建立连接(onServiceConnected)后, 将这个接口类以参数形式传入:
mIVoiceTransferMgr.setVoiceTransferListener(mVoiceTransferListener);
3、设置好了以后,在Server端需要数据传输时,执行registerVoiceTransfer的接口方法,断开数据传输时,执行unregisterVoiceTransfer。例如在Server端的service中onStartCommand方法作如下处理:
publicint onStartCommand(Intent intent, int flags, int startId) {
if (intent == null) {
return START_STICKY;
}
String voiceTransfer =intent.getStringExtra("VoiceTransfer");
if ("start".equals(voiceTransfer)){
mIsSendVoiceData = true;
if (mIVoiceTransferListener != null){
try {
mIVoiceTransferListener.registerVoiceTransfer();
} catch (RemoteException e) {
e.printStackTrace();
}
}
} else if ("stop".equals(voiceTransfer)){
mIsSendVoiceData = false;
if (mIVoiceTransferListener != null){
try {
mIVoiceTransferListener.unregisterVoiceTransfer();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
return START_STICKY;
}
在Server端执行到mIVoiceTransferListener.registerVoiceTransfer()时,Client端相应执行registerVoiceTransfer():
privateIVoiceTransferListener mVoiceTransferListener = new IVoiceTransferListener.Stub(){
@Override
public void registerVoiceTransfer() throwsRemoteException {
mIsSendVoip = true;
setEnableVoip(mIsSendVoip);
}
@Override
public void unregisterVoiceTransfer()throws RemoteException {
mIsSendVoip = false;
setEnableVoip(mIsSendVoip);
}
};
Client端收到注册通知后,设置一些状态以及开启数据传输接口。这样就起到控制数据传输的目的了。
网友评论