一、场景
最近开发过程中,遇到了这样的场景,aidl在service和client通信的过程中,一个service需要同时绑定多个client进行通信。
一开始我的想法是:
这种写法绑定多个客户端是有问题的,绑定了一个没有解绑的话,其他client是不会走这个onBind方法。
因为这是Android四大组件之一的Service的机制决定的。一个service经过bindService之后,再次去bindService,是不会再走onBind回调的。
二、解决办法(一个Service返回多种Binder的能力)
为了减少Service占用资源,应该尽量减少Service的数量,而Service的onBind方法再被绑定后会返回一个Binder,如果没有解绑,就不会再执行onBind方法了,所以即使第二次再intent中传入了不同类型的来获取新的Binder,也是不成功的。
解决的方法:Service返回一个工厂类binder,通过这个工厂类binder来生成不同的binder即可。
首先创建一个IBinderFactory.aidl
interface IBinderFactory {
IBinder generateBinder(int binderType);
}
在Binder实现类中,根据binderType返回不同的Binder,具体代码如下:
@Override
public IBinder onBind(Intent intent) {
return new BinderFactory();
}
class BinderFactory extends IBinderFactory.Stub {
@Override
public IBinder generateBinder(int binderType) throws RemoteException {
IBinder binder;
switch (binderType) {
case TYPE_MY_BINDER:
default:
binder = new MyBinder();
}
return binder;
}
}
客户端先获得BinderFactory,再获得MyBinder
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//在服务连接成功后进行调用
IBinderFactory iBinderFactory = IBinderFactory.Stub.asInterface(service);
IMyAidlInterface iMyAidlInterface = null;
try {
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(iBinderFactory.generateBinder(TYPE_MY_BINDER));
} catch (RemoteException e) {
e.printStackTrace();
}
}
客户端demo地址:https://github.com/sunbinkang/AIDLClient/tree/t0
服务端demo地址:https://github.com/sunbinkang/AIDLService/tree/t0