Android中使用Flow封装一个FlowBus工具类
做过Android的同学应该都使用过EvenutBus、Rxbus、LiveDataBus、LiveData等,这些第三方不仅要导入依赖包,而且还要注册和取消注册,使用起来非常麻烦,稍不注意就导致内存泄漏,自从接触了Flow、SharedFlow之后感觉使用起来方便多了,于是产生了一个封装通用事件工具类的想法,直接上代码.
1.FlowBus:
/**
* @auth: njb
* @date: 2024/7/18 10:17
* @desc: 基于Flow封装的FlowBus
*/
object FlowBus {
private const val TAG = "FlowBus"
private val busMap = mutableMapOf<String, FlowEventBus<*>>()
private val busStickMap = mutableMapOf<String, FlowStickEventBus<*>>()
@Synchronized
fun <T> with(key: String): FlowEventBus<T> {
var flowEventBus = busMap[key]
if (flowEventBus == null) {
flowEventBus = FlowEventBus<T>(key)
busMap[key] = flowEventBus
}
return flowEventBus as FlowEventBus<T>
}
@Synchronized
fun <T> withStick(key: String): FlowStickEventBus<T> {
var stickEventBus = busStickMap[key]
if (stickEventBus == null) {
stickEventBus = FlowStickEventBus<T>(key)
busStickMap[key] = stickEventBus
}
return stickEventBus as FlowStickEventBus<T>
}
open class FlowEventBus<T>(private val key: String) : DefaultLifecycleObserver {
//私有对象用于发送消息
private val _events: MutableSharedFlow<T> by lazy {
obtainEvent()
}
//暴露的公有对象用于接收消息
private val events = _events.asSharedFlow()
open fun obtainEvent(): MutableSharedFlow<T> =
MutableSharedFlow(0, 1, BufferOverflow.DROP_OLDEST)
//在主线程中接收数据
fun register(lifecycleOwner: LifecycleOwner,action: (t: T) -> Unit){
lifecycleOwner.lifecycleScope.launch {
events.collect {
try {
action(it)
}catch (e:Exception){
e.printStackTrace()
Log.e(TAG, "FlowBus - Error:$e")
}
}
}
}
//在协程中接收数据
fun register(scope: CoroutineScope,action: (t: T) -> Unit){
scope.launch {
events.collect{
try {
action(it)
}catch (e:Exception){
e.printStackTrace()
Log.e(TAG, "FlowBus - Error:$e")
}
}
}
}
//在协程中发送数据
suspend fun post(event: T){
_events.emit(event)
}
//在主线程中发送数据
fun post(scope: CoroutineScope,event: T){
scope.launch {
_events.emit(event)
}
}
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
Log.w(TAG, "FlowBus ==== 自动onDestroy")
val subscriptCount = _events.subscriptionCount.value
if (subscriptCount <= 0)
busMap.remove(key)
}
// 手动调用的销毁方法,用于Service、广播等