在 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.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
}
}
- 使用示例
基本使用方式
// 定义广播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)
}
}
- 更高级的封装 - 使用 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)
}
}
- 生命周期感知的封装
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)
}
}
主要特点
- 单例管理:确保广播管理器的唯一实例
- 自动清理:提供统一的注销方法,避免内存泄漏
- 灵活注册:支持多种注册方式和参数配置
- DSL支持:提供更优雅的API使用方式
- 生命周期感知:与Android生命周期无缝集成
- 错误处理:包含异常捕获,提高稳定性
这种封装方式可以帮助你更好地管理动态注册的广播,避免常见的内存泄漏问题,并提供更简洁的API接口。