Android 本地广播 LocalBroadcastManager
重点提醒:
LocalBroadcastManager在 AndroidX 里已经废弃,官方推荐改用LiveData/Flow做应用内通信,但面试依然会考。
一、本地广播是什么(对比全局广播)
全局广播(前面学的 sendBroadcast / sendOrderedBroadcast)
- 走系统AMS,跨应用,所有APP都能收到这条广播
- 安全隐患:数据容易被别的App截获;别的App也可以伪造广播攻击我们App
本地广播 LocalBroadcastManager
- 广播只在当前App内部流转,不会经过系统全局广播机制,别的应用完全收不到 ✅ 优点:
- 安全:广播不会泄露到外部App,外部App无法发送广播进来冒充
- 高效:不需要跨进程和系统AMS交互,速度更快
- 不需要申请权限 限制:
- 只能动态注册,不支持静态注册(AndroidManifest里面写receiver无效)
- 仅在同一个App内生效,不能跨进程、跨App
- 不支持和系统广播一起使用
二、完整代码拆解
1. 自定义接收器 MyReceiver
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "接收到本地广播", Toast.LENGTH_LONG).show();
}
}
Code language: PHP (php)
2. Activity 中使用 LocalBroadcastManager
package cn.bamn.www.localcastdmeo;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private LocalBroadcastManager localBroadcastManager;//本地广播管理器引用
private IntentFilter intentFilter;
private MyReceiver myReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取本地广播管理器单例
localBroadcastManager = LocalBroadcastManager.getInstance(this);
Button button = (Button) findViewById(R.id.btn_send);
button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
// 构造Intent Action,发送本地广播
Intent intent = new Intent("com.foxdevelop.www.LocalCastDemo.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent);
}
});
// 动态注册本地广播接收器
intentFilter = new IntentFilter();
intentFilter.addAction("com.foxdevelop.www.LocalCastDemo.LOCAL_BROADCAST");
myReceiver = new MyReceiver();
localBroadcastManager.registerReceiver(myReceiver,intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
// 必须反注册!防止内存泄漏
localBroadcastManager.unregisterReceiver(myReceiver);
}
}
Code language: JavaScript (javascript)
核心API:
LocalBroadcastManager.getInstance(context):获取实例(单例)registerReceiver(receiver, intentFilter):动态注册接收器sendBroadcast(intent):发送本地无序广播;sendOrderedBroadcast()本地有序广播unregisterReceiver():页面销毁取消注册,必写,内存泄漏大坑
三、本地广播、无序全局广播、有序全局广播 对比汇总
| 类型 | 通信范围 | 是否跨App | 能否截断 | 注册方式 | 底层机制 |
|---|---|---|---|---|---|
| 全局无序广播 sendBroadcast | 全局 | 可以跨App | 不能abort | 静态+动态 | 系统AMS跨进程 |
| 全局有序广播 sendOrderedBroadcast | 全局 | 可以跨App | abortBroadcast截断 | 静态+动态 | 系统AMS跨进程,按priority串行 |
| 本地广播 LocalBroadcastManager | 本应用内 | 不能跨App | 支持有序广播截断 | 仅动态注册 | 内存内分发,不走AMS,效率高 |
Previous: 有序广播