目录
一、什么是BroadcastReceiver
二、创建和使用BroadcastReceiver
三、跨应用广播接收权限
四、广播方式
五、广播类型与特性
六、BroadcasReceiver注册方式
七、BroadcasReceiver工作流程
你可以把广播接收器想象成一个“收音机”。它的作用是监听系统或应用发出的“广播消息”,并在收到消息后执行相应的操作。
BroadcastReceiver用于监听系统或应用发出的广播事件,实现跨组件通信。其特点是发送方无需关注接收方是否存在或如何处理数据。
1. 广播的类型
ACTION_BATTERY_LOW:电池电量低。
ACTION_BOOT_COMPLETED:设备启动完成。
在App中定义一个广播,比如“任务完成”,然后在其他地方接收并处理。
2. 生命周期管理
广播接收器的生命周期非常短暂,它只存在于接收到广播并处理完广播的这段时间内。
3. 典型场景
典型场景 | 实现方案 |
---|---|
强制下线功能 | 发送全局广播通知所有界面退出登录,动态注册接收器处理跳转逻辑 |
多应用协同 | 通过自定义广播与权限控制,实现应用间数据传递与功能触发 |
系统事件响应 | 静态注册监听 SCREEN_ON /SCREEN_OFF 等系统广播,实现锁屏/亮屏逻辑 |
1. 继承基类
新建类继承 BroadcastReceiver
,并重写 onReceive()
方法:
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// 处理广播逻辑,如弹出 Toast
Toast.makeText(context, "收到广播", Toast.LENGTH_SHORT).show();
}
}
onReceive()
方法执行时间需控制在 10 秒内,否则会触发 ANR 错误。建议复杂逻辑通过
IntentService
或WorkManager
异步处理。
2. 注册广播接收器
广播接收器可以通过两种方式注册:
动态注册(接收方代码中注册):需手动注册和注销,生命周期与注册的 Context(如 Activity)绑定,应用关闭后失效。
// 注册
IntentFilter filter = new IntentFilter("CUSTOM_ACTION");
MyReceiver receiver = new MyReceiver();
registerReceiver(receiver, filter);
// 注销(如 onDestroy 中)
unregisterReceiver(receiver);
为避免内存泄漏,动态注册的接收器需在适当时机(如
onDestroy()
)注销 。
静态注册(接收方AndroidManifest.xml):应用未启动时也能接收广播(如系统启动完成事件),但 Android 8.0+ 对隐式广播有限制。
// BroadcastReceiver使用者(接收方)的AndroidManifest.xml
// 允许应用监听设备启动完成的广播
Android 8.0+ 限制:针对隐式广播(非定向广播),静态注册可能失效,需改用动态注册或使用豁免列表中的广播 。
3. 发送广播
Intent intent = new Intent("CUSTOM_ACTION");
intent.putExtra("data", "Hello");
sendBroadcast(intent);
// 发送方代码:发送有序广播
Intent intent = new Intent("ORDERED_ACTION");
sendOrderedBroadcast(intent, null);
// 接收方配置:接收器中设置优先级(AndroidManifest.xml)
// 接收方代码:在 onReceive() 中拦截广播
abortBroadcast();
敏感广播需添加权限控制,防止恶意应用拦截。
场景 | 发送方配置 | 接收方配置 |
---|---|---|
sendBroadcast() 附加权限 |
定义 ,无需声明权限 |
声明
|
设置权限 |
声明
|
定义 在 中绑定 |
1. 发送方通过 sendBroadcast()
附加权限
发送方需在自身 AndroidManifest.xml
中通过
标签定义权限。
发送广播时需指定此权限:
sendBroadcast(intent, "com.example.SEND_PERMISSION");
发送方无需通过
声明该权限,而接收方需在 Manifest 中声明该权限,否则无法接收广播:
若权限的
protectionLevel
设为signature
,发送方与接收方需使用相同签名。也就是说,发送方与接收方应用必须使用相同的数字证书(即开发者签名密钥)进行签名。
2. 接收方通过
标签的 android:permission
属性限制发送方权限
接收方需在 Manifest 中定义新权限(如 RECEIVE_PERMISSION
),并在
标签中设置:
...
发送方需在自己的 Manifest 中声明该权限,否则发送的广播会被接收方拒绝:
系统广播应用场景
- 监听开机启动:静态注册
BOOT_COMPLETED
广播,需声明权限RECEIVE_BOOT_COMPLETED
。- 监听网络变化:动态注册
CONNECTIVITY_CHANGE
广播,需权限ACCESS_NETWORK_STATE
特性 | 显式广播 | 隐式广播 |
---|---|---|
目标范围 | 明确指定接收方组件或包名 | 通过 IntentFilter 匹配所有符合条件的接收方 |
注册限制 | 允许接收方静态注册(Android 8.0+ 无限制) | 禁止接收方静态注册(Android 8.0+ 限制) |
通信范围 | 适用于定向通信(如应用内部或特定合作应用) | 适用于广播全局事件(如系统事件通知) |
安全性 | 更高(需明确目标权限或签名验证) | 较低(可能被恶意应用劫持) |
1. 显示广播
Intent intent = new Intent("CUSTOM_ACTION");
intent.setPackage("com.example.receiverapp"); // 限定接收方包名
sendBroadcast(intent);
Intent intent = new Intent("CUSTOM_ACTION");
intent.setComponent(
new ComponentName("com.example.receiverapp", "com.example.ReceiverClass"));
sendBroadcast(intent);
显式广播通过精确指定接收方身份,绕过 Android 8.0+ 对隐式广播静态注册的限制,适用于需定向通信的场景。开发者应优先使用动态注册或显式广播,确保应用兼容性及安全性。
2. 隐式广播
发送方仅定义 Action
,依赖接收方声明的 IntentFilter
匹配广播,适用于全局事件通知。
Intent intent = new Intent("CUSTOM_ACTION");
sendBroadcast(intent); // 不指定目标接收方
隐式广播的发送方仅需在代码中定义
Intent
的Action
并发送,无需在 XML 文件中进行任何配置。接收方需自行处理IntentFilter
的注册与适配规则。
1. 普通广播(标准广播)
所有接收器并行接收,无顺序限制,无法终止传播。
sendBroadcast(new Intent("com.example.ACTION_STANDARD"));
2. 有序广播(Ordered Broadcast)
接收器按优先级顺序处理,可中断传播或修改数据。
发送方式:
sendOrderedBroadcast(intent, null);
接收方注册:
3. 本地广播(Local Broadcast)
仅在应用内部传递广播,避免跨应用风险(已弃用 LocalBroadcastManager
,推荐 LiveData
或 RxJava
替代)。
本地广播发送方式:
Intent localIntent = new Intent("com.example.ACTION_LOCAL");
LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
对比维度 | 静态注册 | 动态注册 |
---|---|---|
注册方式 | 在 AndroidManifest.xml 中通过 标签声明 |
在代码中通过 registerReceiver() 动态注册,需手动管理生命周期 |
生命周期管理 | 独立于组件生命周期,系统自动创建和销毁(应用未运行也可接收广播) | 与注册上下文(如 Activity /Service )生命周期绑定,需在 onDestroy() 中手动注销 |
注册时机 | 应用安装时完成,全局生效 | 运行时按需注册,作用域可控 |
广播类型适配 | Android 8.0+ 受限:仅支持接收豁免的系统隐式广播 | 无条件支持所有广播类型(显式/隐式) |
系统兼容性 | 需适配 Android 8.0+ 隐式广播限制 | 无版本限制,适配性更强 |
性能影响 | 长期占用系统资源(应用安装时即注册,增加系统负载) | 按需注册和释放资源,内存占用更灵活 |
安全性 | 潜在风险:恶意应用可能监听隐式广播 | 可控性高:仅应用运行时生效,且可限制接收范围(如权限控制) |
适用场景 | 需长期监听系统事件(如开机启动、网络变化) | 临时监听应用内事件(如用户交互触发的自定义广播) |
代码复杂度 | 配置简单,无需额外代码管理 | 需编写注册/注销代码,逻辑复杂度更高 |
内存泄漏风险 | 无 | 未及时注销会导致内存泄漏 |
资源占用 | 长期占用系统资源,可能影响性能 | 按需释放资源,优化内存使用 |
Android 8.0+ 隐式广播限制:
ACTION_BOOT_COMPLETED
)。安全性建议:
android:permission
)限制接收方。LocalBroadcastManager
(已弃用)或 LiveData
替代高频广播场景。长期系统监听用静态注册,临时或安全敏感场景用动态注册。
避免静态注册高频广播,动态注册按需启停更灵活。
1. 静态注册示例
接收方创建 BroadcastReceiver 子类
public class MyStaticReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if ("com.example.STATIC_ACTION".equals(action)) {
String data = intent.getStringExtra("data");
Toast.makeText(context, "静态接收器: " + data, Toast.LENGTH_SHORT).show();
}
}
}
接收方在 AndroidManifest.xml
中声明
// 允许应用监听设备启动完成的广播
发送方发送广播代码
Intent intent = new Intent("com.example.STATIC_ACTION");
intent.putExtra("data", "静态广播测试");
sendBroadcast(intent);
在 Android 3.1+ 系统中,应用需至少被用户手动启动一次;否则,即使声明权限,也无法接收开机广播。
部分厂商系统(如 MIUI、EMUI)可能默认禁止应用自启动,需用户手动开启。
2. 动态注册示例
接收方在 Activity 中注册与注销
public class MainActivity extends AppCompatActivity {
private BroadcastReceiver dynamicReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 动态注册接收器
dynamicReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String data = intent.getStringExtra("data");
Toast.makeText(context, "动态接收器: "
+ data, Toast.LENGTH_SHORT).show();
}
};
IntentFilter filter = new IntentFilter("com.example.DYNAMIC_ACTION");
registerReceiver(dynamicReceiver, filter);
}
@Override
protected void onDestroy() {
super.onDestroy();
// 必须手动注销
unregisterReceiver(dynamicReceiver);
}
}
发送方发送广播
Intent intent = new Intent("com.example.DYNAMIC_ACTION");
intent.putExtra("data", "动态广播测试");
sendBroadcast(intent);
动态注册未及时调用
unregisterReceiver()会
导致内存泄漏。此外,在
onPause()
或onDestroy()
中要及时注销接收器。
BroadcastReceiver的核心抽象类是android.content.BroadcastReceiver
public abstract class BroadcastReceiver {
// 核心方法,用于接收广播
public abstract void onReceive(Context context, Intent intent);
// 其他方法,比如设置结果、获取结果等
public final void setResultCode(int code) { ... }
public final int getResultCode() { ... }
public final void setResultData(String data) { ... }
public final String getResultData() { ... }
public final void setResultExtras(Bundle extras) { ... }
public final Bundle getResultExtras(boolean makeMap) { ... }
}
无论是静态还是动态注册,系统默认每次广播触发时都会创建新的BroadcastReceiver实例,并在
onReceive()
执行完毕后销毁 。静态注册的接收器每次均由系统创建新实例,无法复用旧实例,因此不存在同一实例多次响应广播的情况。
动态注册时未及时调用
unregisterReceiver()
,导致同一接收器实例被多次注册(如多次跳转同一 Activity 且未解注册),广播触发时系统会多次调用该实例的onReceive()
。
// Activity 中重复注册同一接收器
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter("com.example.ACTION_TEST");
registerReceiver(receiver, filter); // 每次 Activity 创建都会注册一次
}
适配建议:遵循生命周期管理原则,避免非预期的重复注册与逻辑执行。