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

发布于:2025-09-07 ⋅ 阅读:(13) ⋅ 点赞:(0)

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

  1. 基础封装类
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. 使用示例

基本使用方式

// 定义广播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 方式
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 使用示例

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. 生命周期感知的封装
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: 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接口。


网站公告

今日签到

点亮在社区的每一天
去签到