Android Kotlin 动态注册 Broadcast 的完整封装方案

在 Kotlin 中封装动态注册的 Broadcast 可以让你更优雅地管理广播的注册和注销,避免内存泄漏。下面是一个完整的封装方案:

  1. 基础封装类
kotlin 复制代码
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Handler
import android.os.Looper

class DynamicBroadcastManager private constructor() {

    private val receivers = mutableMapOf<Context, MutableList<BroadcastReceiver>>()
    private val intentFilters = mutableMapOf<BroadcastReceiver, IntentFilter>()

    companion object {
        @Volatile
        private var instance: DynamicBroadcastManager? = null

        fun 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
    }
}
  1. 使用示例

基本使用方式

kotlin 复制代码
// 定义广播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: NetworkChangeReceiver
    private val broadcastManager = DynamicBroadcastManager.getInstance()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 初始化广播接收器
        networkReceiver = NetworkChangeReceiver()

        // 注册广播
        registerBroadcasts()
    }

    private fun registerBroadcasts() {
        // 创建IntentFilter
        val 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)
    }
}
  1. 更高级的封装 - 使用 DSL 方式
kotlin 复制代码
class BroadcastBuilder {
    private val actions = mutableListOf<String>()
    private var permission: String? = null
    private var handler: Handler? = null

    fun 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 使用示例

kotlin 复制代码
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)
    }
}
  1. 生命周期感知的封装
kotlin 复制代码
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()
    }
}

生命周期感知使用示例

kotlin 复制代码
class MainActivity : AppCompatActivity() {

    private lateinit var lifecycleAwareManager: LifecycleAwareBroadcastManager

    override 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)
    }
}

主要特点

  1. 单例管理:确保广播管理器的唯一实例
  2. 自动清理:提供统一的注销方法,避免内存泄漏
  3. 灵活注册:支持多种注册方式和参数配置
  4. DSL支持:提供更优雅的API使用方式
  5. 生命周期感知:与Android生命周期无缝集成
  6. 错误处理:包含异常捕获,提高稳定性

这种封装方式可以帮助你更好地管理动态注册的广播,避免常见的内存泄漏问题,并提供更简洁的API接口。

相关推荐
金融RPA机器人丨实在智能5 分钟前
Android Studio开发App项目进入AI深水区:实在智能Agent引领无代码交互革命
android·人工智能·ai·android studio
科技块儿6 分钟前
利用IP查询在智慧城市交通信号系统中的应用探索
android·tcp/ip·智慧城市
独行soc36 分钟前
2026年渗透测试面试题总结-18(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
王码码20351 小时前
Flutter for OpenHarmony 实战之基础组件:第二十七篇 BottomSheet — 动态底部弹窗与底部栏菜单
android·flutter·harmonyos
2501_915106321 小时前
app 上架过程,安装包准备、证书与描述文件管理、安装测试、上传
android·ios·小程序·https·uni-app·iphone·webview
vistaup1 小时前
OKHTTP 默认构建包含 android 4.4 的TLS 1.2 以及设备时间不对兼容
android·okhttp
常利兵1 小时前
ButterKnife在Android 35 + Gradle 8.+环境下的适配困境与现代化迁移指南
android
撩得Android一次心动1 小时前
Android LiveData 全面解析:使用Java构建响应式UI【源码篇】
android·java·android jetpack·livedata
熊猫钓鱼>_>2 小时前
移动端开发技术选型报告:三足鼎立时代的开发者指南(2026年2月)
android·人工智能·ios·app·鸿蒙·cpu·移动端
Rainman博12 小时前
WMS-窗口relayout&FinishDrawing
android