AIDL使用监听需要考虑多个第三方App同时添加监听,这时候需要一个队列去管理接口,一开始使用
val listenerMap = mutableMapOf<Class<*>, MutableSet<IInterface>>()
使用过程中发现添加监听没有问题,但是移除就不行了,因为多次跨进程传输客户端的对象在服务端中生成不同的对象,虽然添加和移除在客户端端中是同一个对象,但是通过AIDL传递到服务端就是两个对象,所以无法移除,但是它们底层的Binder对象是同一个,所以可以使用asBinder
var binder = (listener as IInterface).asBinder();
var listenerSet = listenerMap[clazz]
listenerSet?.let {
for (listener in it) {
if (listener.asBinder() == binder){
listenerSet.remove(listener)
}
}
}
或者使用RemoteCallbackList
val listenerMap = mutableMapOf<Class<*>, RemoteCallbackList<IInterface>>()
inline fun <reified T> addListener(listener: T, clazz: Class<T>): Int {
listenerMap.getOrPut(clazz, { RemoteCallbackList() }).register(listener as IInterface)
var remoteCallbackList = listenerMap[clazz]
var num = remoteCallbackList?.beginBroadcast()
remoteCallbackList?.finishBroadcast()
return num?:-1;
}
inline fun <reified T> removeListener(listener: T, clazz: Class<T>): Int {
var remoteCallbackList = listenerMap[clazz]
remoteCallbackList?.unregister(listener as IInterface)
var num = remoteCallbackList?.beginBroadcast()
remoteCallbackList?.finishBroadcast()
return num?:-1;
}
fun sendData(data: Int) {
var remoteCallbackList = listenerMap.get(OnListener::class.java)
remoteCallbackList?.let {
var num = remoteCallbackList.beginBroadcast();
for (i in 0 until num) {
var listener = remoteCallbackList.getBroadcastItem(i) as OnListener
if (listener!=null){
listener.onData(data)
}
}
remoteCallbackList.finishBroadcast();
}
}