一句话说透Android里面的BroadcastReceiver和LocalBroadcastReceiver的区别

110 阅读2分钟

一句话总结:
BroadcastReceiver 是“全城广播”,能接收全系统的消息(但容易被偷听);LocalBroadcastReceiver 是“公司内部对讲机”,只在应用内通信,安全又高效!


核心区别对比表

对比项BroadcastReceiver(全局广播)LocalBroadcastReceiver(本地广播)
通信范围全系统(跨应用)仅当前应用内部
安全性低(可能被其他应用监听或伪造消息)高(消息仅在应用内传递)
性能低(跨进程通信,开销大)高(应用内直接传递,无跨进程开销)
是否需要权限需要(防止恶意广播)不需要
典型场景监听系统事件(如网络变化、电量不足)应用内组件通信(如 Activity 和 Service)

详细解释

1. BroadcastReceiver(全局广播)

  • 工作原理

    • 像“电台广播”,任何应用都能发送或接收消息(需权限控制)。
    • 消息通过系统进程传递,跨应用通信。
  • 代码示例

    // 发送全局广播  
    val intent = Intent("MY_ACTION")  
    sendBroadcast(intent)  
    
    // 接收全局广播(需在 AndroidManifest.xml 注册或动态注册)  
    val receiver = object : BroadcastReceiver() {  
        override fun onReceive(context: Context?, intent: Intent?) {  
            // 处理广播  
        }  
    }  
    registerReceiver(receiver, IntentFilter("MY_ACTION"))  
    
  • 缺点

    • 安全风险:恶意应用可能伪造广播或窃听数据。
    • 性能问题:跨进程通信导致延迟和资源消耗。

2. LocalBroadcastReceiver(本地广播)

  • 工作原理

    • 像“公司内部对讲机”,消息只在应用内传递,不经过系统进程。
    • 基于 LocalBroadcastManager(已废弃,推荐替代方案见文末)。
  • 代码示例

    // 发送本地广播  
    val intent = Intent("MY_LOCAL_ACTION")  
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent)  
    
    // 接收本地广播(需动态注册,无需 AndroidManifest.xml)  
    val receiver = object : BroadcastReceiver() {  
        override fun onReceive(context: Context?, intent: Intent?) {  
            // 处理广播  
        }  
    }  
    LocalBroadcastManager.getInstance(this)  
        .registerReceiver(receiver, IntentFilter("MY_LOCAL_ACTION"))  
    
  • 优点

    • 安全:消息不跨应用,避免被窃听或伪造。
    • 高效:应用内直接通信,无跨进程开销。

实际场景对比

场景 1:监听网络状态变化

  • 选择全局广播

    // 注册系统广播  
    val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)  
    registerReceiver(networkReceiver, filter)  
    

场景 2:Activity 通知 Service 更新数据

  • 选择本地广播

    // Activity 发送本地广播  
    LocalBroadcastManager.getInstance(this).sendBroadcast(Intent("UPDATE_DATA"))  
    
    // Service 接收本地广播  
    LocalBroadcastManager.getInstance(this)  
        .registerReceiver(dataReceiver, IntentFilter("UPDATE_DATA"))  
    

替代方案(LocalBroadcastManager 已废弃)

Google 推荐使用以下更现代的通信方式替代本地广播:

  1. LiveData + ViewModel

    // ViewModel 中定义 LiveData  
    class MyViewModel : ViewModel() {  
        val message = MutableLiveData<String>()  
    }  
    
    // Activity 观察数据变化  
    viewModel.message.observe(this) { msg ->  
        // 处理消息  
    }  
    
    // Service 或其他组件更新数据  
    viewModel.message.value = "New Message"  
    
  2. Kotlin Flow

    // 定义 Flow  
    private val _messages = MutableSharedFlow<String>()  
    val messages: SharedFlow<String> = _messages.asSharedFlow()  
    
    // 发送消息  
    _messages.emit("Hello")  
    
    // 接收消息  
    lifecycleScope.launch {  
        messages.collect { msg ->  
            // 处理消息  
        }  
    }  
    

总结口诀

“全局广播跨应用,监听系统很方便,
安全风险要当心,跨进程还耗资源。
本地广播应用内,高效安全无隐患,
官方推荐已废弃,LiveData/Flow 更推荐!”