在 Kotlin 中封装动态注册的 Broadcast 可以让你更优雅地管理广播的注册和注销,避免内存泄漏。下面是一个完整的封装方案:
- 基础封装类
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Handler
import android.os.Looperclass DynamicBroadcastManager private constructor() {private val receivers = mutableMapOf<Context, MutableList<BroadcastReceiver>>()private val intentFilters = mutableMapOf<BroadcastReceiver, IntentFilter>()companion object {@Volatileprivate var instance: DynamicBroadcastManager? = nullfun getInstance(): DynamicBroadcastManager {return instance ?: synchronized(this) {instance ?: DynamicBroadcastManager().also { instance = it }}}}/*** 注册广播接收器* @param context 上下文* @param receiver 广播接收器* @param filter 意图过滤器* @param permission 权限(可选)* @param handler Handler(可选)*/fun registerReceiver(context: Context,receiver: BroadcastReceiver,filter: IntentFilter,permission: String? = null,handler: Handler? = null) {try {context.registerReceiver(receiver, filter, permission, handler)// 保存注册信息if (!receivers.containsKey(context)) {receivers[context] = mutableListOf()}receivers[context]?.add(receiver)intentFilters[receiver] = filter} catch (e: Exception) {e.printStackTrace()}}/*** 注销广播接收器* @param context 上下文* @param receiver 广播接收器*/fun unregisterReceiver(context: Context, receiver: BroadcastReceiver) {try {context.unregisterReceiver(receiver)receivers[context]?.remove(receiver)intentFilters.remove(receiver)// 如果该context没有其他接收器,移除记录if (receivers[context]?.isEmpty() == true) {receivers.remove(context)}} catch (e: Exception) {e.printStackTrace()}}/*** 注销指定上下文的所有广播接收器* @param context 上下文*/fun unregisterAllReceivers(context: Context) {receivers[context]?.let { receiverList ->val copyList = receiverList.toList() // 创建副本避免并发修改copyList.forEach { receiver ->unregisterReceiver(context, receiver)}}}/*** 获取指定接收器的IntentFilter* @param receiver 广播接收器*/fun getIntentFilter(receiver: BroadcastReceiver): IntentFilter? {return intentFilters[receiver]}/*** 检查接收器是否已注册* @param context 上下文* @param receiver 广播接收器*/fun isReceiverRegistered(context: Context, receiver: BroadcastReceiver): Boolean {return receivers[context]?.contains(receiver) ?: false}
}
- 使用示例
基本使用方式
// 定义广播Action常量
object BroadcastActions {const val NETWORK_CHANGED = "android.net.conn.CONNECTIVITY_CHANGE"const val CUSTOM_ACTION = "com.example.app.CUSTOM_ACTION"
}// 创建广播接收器
class NetworkChangeReceiver : BroadcastReceiver() {override fun onReceive(context: Context?, intent: Intent?) {when (intent?.action) {BroadcastActions.NETWORK_CHANGED -> {// 处理网络变化handleNetworkChange(context, intent)}BroadcastActions.CUSTOM_ACTION -> {// 处理自定义广播handleCustomAction(context, intent)}}}private fun handleNetworkChange(context: Context?, intent: Intent?) {// 网络变化处理逻辑}private fun handleCustomAction(context: Context?, intent: Intent?) {// 自定义广播处理逻辑}
}// 在Activity或Fragment中使用
class MainActivity : AppCompatActivity() {private lateinit var networkReceiver: NetworkChangeReceiverprivate val broadcastManager = DynamicBroadcastManager.getInstance()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 初始化广播接收器networkReceiver = NetworkChangeReceiver()// 注册广播registerBroadcasts()}private fun registerBroadcasts() {// 创建IntentFilterval filter = IntentFilter().apply {addAction(BroadcastActions.NETWORK_CHANGED)addAction(BroadcastActions.CUSTOM_ACTION)}// 注册广播接收器broadcastManager.registerReceiver(this, networkReceiver, filter)}override fun onDestroy() {super.onDestroy()// 注销广播接收器broadcastManager.unregisterAllReceivers(this)}// 发送自定义广播private fun sendCustomBroadcast() {val intent = Intent(BroadcastActions.CUSTOM_ACTION).apply {putExtra("data", "Hello from MainActivity!")}sendBroadcast(intent)}
}
- 更高级的封装 - 使用 DSL 方式
class BroadcastBuilder {private val actions = mutableListOf<String>()private var permission: String? = nullprivate var handler: Handler? = nullfun action(action: String) = apply { actions.add(action) }fun actions(vararg actions: String) = apply { this.actions.addAll(actions) }fun permission(permission: String?) = apply { this.permission = permission }fun handler(handler: Handler?) = apply { this.handler = handler }fun build(): IntentFilter {return IntentFilter().apply {actions.forEach { addAction(it) }}}
}// DSL扩展函数
inline fun broadcastReceiver(context: Context,crossinline onReceive: (Context, Intent) -> Unit
): BroadcastReceiver {return object : BroadcastReceiver() {override fun onReceive(context: Context, intent: Intent) {onReceive(context, intent)}}
}// 使用DSL方式注册广播
fun DynamicBroadcastManager.registerWithDSL(context: Context,receiver: BroadcastReceiver,builder: BroadcastBuilder.() -> Unit
) {val broadcastBuilder = BroadcastBuilder().apply(builder)val filter = broadcastBuilder.build()registerReceiver(context, receiver, filter, broadcastBuilder.permission, broadcastBuilder.handler)
}
DSL 使用示例
class MainActivity : AppCompatActivity() {private val broadcastManager = DynamicBroadcastManager.getInstance()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 使用DSL方式注册广播val receiver = broadcastReceiver(this) { context, intent ->when (intent.action) {BroadcastActions.NETWORK_CHANGED -> {// 处理网络变化}BroadcastActions.CUSTOM_ACTION -> {val data = intent.getStringExtra("data")// 处理数据}}}broadcastManager.registerWithDSL(this, receiver) {action(BroadcastActions.NETWORK_CHANGED)action(BroadcastActions.CUSTOM_ACTION)permission(android.Manifest.permission.ACCESS_NETWORK_STATE)handler(Handler(Looper.getMainLooper()))}}override fun onDestroy() {super.onDestroy()broadcastManager.unregisterAllReceivers(this)}
}
- 生命周期感知的封装
class LifecycleAwareBroadcastManager(private val context: Context,private val lifecycle: Lifecycle
) : DefaultLifecycleObserver {private val receivers = mutableListOf<Pair<BroadcastReceiver, IntentFilter>>()private val broadcastManager = DynamicBroadcastManager.getInstance()init {lifecycle.addObserver(this)}fun registerReceiver(receiver: BroadcastReceiver, filter: IntentFilter) {receivers.add(receiver to filter)if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {broadcastManager.registerReceiver(context, receiver, filter)}}@OnLifecycleEvent(Lifecycle.Event.ON_START)fun onStart() {receivers.forEach { (receiver, filter) ->broadcastManager.registerReceiver(context, receiver, filter)}}@OnLifecycleEvent(Lifecycle.Event.ON_STOP)fun onStop() {receivers.forEach { (receiver, _) ->broadcastManager.unregisterReceiver(context, receiver)}}@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)fun onDestroy() {lifecycle.removeObserver(this)receivers.clear()}
}
生命周期感知使用示例
class MainActivity : AppCompatActivity() {private lateinit var lifecycleAwareManager: LifecycleAwareBroadcastManageroverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)lifecycleAwareManager = LifecycleAwareBroadcastManager(this, lifecycle)val receiver = broadcastReceiver(this) { context, intent ->// 处理广播}val filter = IntentFilter(BroadcastActions.NETWORK_CHANGED)lifecycleAwareManager.registerReceiver(receiver, filter)}
}
主要特点
- 单例管理:确保广播管理器的唯一实例
- 自动清理:提供统一的注销方法,避免内存泄漏
- 灵活注册:支持多种注册方式和参数配置
- DSL支持:提供更优雅的API使用方式
- 生命周期感知:与Android生命周期无缝集成
- 错误处理:包含异常捕获,提高稳定性
这种封装方式可以帮助你更好地管理动态注册的广播,避免常见的内存泄漏问题,并提供更简洁的API接口。