以下是我实现的EventBus(基于coroutine 0.26.1版本)
object EventBus {
//hot observable
val mChannelMap: HashMap<String, BroadcastChannel<Any>> = HashMap()
//cold observable(订阅后会把订阅之前产生的数据推送给订阅者)
// val mChannelMap: HashMap<String, ConflatedBroadcastChannel<Any>> = HashMap()
val mJobMap: HashMap<String, CoroutineContext> = HashMap()
inline fun <reified E> post(e: E) {
val key = E::class.java.name
if (!mChannelMap.containsKey(key)) {
mChannelMap[key] = BroadcastChannel(1)
}
GlobalScope.launch {
mChannelMap[key]?.send(e as Any)
}
}
inline fun <reified E> registerEvent(noinline action: (E) -> Unit) {
val key = E::class.java.name
if (!mChannelMap.containsKey(key)) {
mChannelMap[key] = BroadcastChannel(1)
}
GlobalScope.launch {
val channel = mChannelMap[key]
mJobMap[key] = coroutineContext
channel?.let {
val receiver = channel.openSubscription().filter { it is E }.map { it as E }
GlobalScope.launch(Dispatchers.Main) {
for (i in receiver) {
action.invoke(i)
}
}
}
}
}
inline fun <reified E> unRegisterEvent() {
val key = E::class.java.name
if (mChannelMap.containsKey(key)) {
mChannelMap[key]?.close()
mChannelMap.remove(key)
}
if (mJobMap.containsKey(key)) {
mJobMap[key]?.cancelChildren()
mJobMap.remove(key)
}
}
}
展开