【Android】四大组件之BroadcastReceiver

06-01 1549阅读

目录

一、什么是BroadcastReceiver

二、创建和使用BroadcastReceiver

三、跨应用广播接收权限

四、广播方式

五、广播类型与特性

六、BroadcasReceiver注册方式

七、BroadcasReceiver工作流程


你可以把广播接收器想象成一个“收音机”。它的作用是监听系统或应用发出的“广播消息”,并在收到消息后执行相应的操作。

一、什么是BroadcastReceiver

BroadcastReceiver用于监听系统或应用发出的广播事件,实现跨组件通信。其特点是发送方无需关注接收方是否存在或如何处理数据。

1. 广播的类型

  • 系统广播:由系统发出,比如电池电量低、网络状态变化、屏幕开关等。

    ACTION_BATTERY_LOW:电池电量低。

    ACTION_BOOT_COMPLETED:设备启动完成。

    • 自定义广播:由应用发出,用于应用内部或应用之间的通信。

      在App中定义一个广播,比如“任务完成”,然后在其他地方接收并处理。

      2. 生命周期管理

      【Android】四大组件之BroadcastReceiver
      (图片来源网络,侵删)

      广播接收器的生命周期非常短暂,它只存在于接收到广播并处理完广播的这段时间内。

      • 接收广播:当广播发出时,系统会创建广播接收器的实例,并调用它的onReceive()方法。
      • 完成任务:onReceive()方法执行完毕后,广播接收器的实例就会被销毁。

        3. 典型场景

        【Android】四大组件之BroadcastReceiver
        (图片来源网络,侵删)
        典型场景‌‌实现方案‌
        ‌强制下线功能‌发送全局广播通知所有界面退出登录,动态注册接收器处理跳转逻辑
        ‌多应用协同‌通过自定义广播与权限控制,实现应用间数据传递与功能触发
        ‌系统事件响应‌静态注册监听 SCREEN_ON/SCREEN_OFF 等系统广播,实现锁屏/亮屏逻辑

        二、创建和使用BroadcastReceiver

        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);  
                      

                      六、BroadcasReceiver注册方式

                      对比维度‌‌静态注册‌‌动态注册‌
                      ‌注册方式‌在 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() 中要及时注销接收器。

                          七、BroadcasReceiver工作流程

                          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) { ... }
                          }
                          • 静态注册:由PackageManagerService解析AndroidManifest.xml并注册。
                          • 动态注册:通过Context.registerReceiver()注册到ActivityManagerService。
                          • 通过Context.sendBroadcast()发送广播,ActivityManagerService负责分发。
                          • 分发广播:BroadcastQueue从队列中取出广播,并调用广播接收器的onReceive()方法处理。
                          • 处理广播:广播接收器的onReceive()方法运行在主线程中,不能执行耗时操作。
                          • 广播流程‌:事件触发 → 封装 Intent → 发送 → 接收处理 → 生命周期管理。

                            无论是静态还是动态注册,‌系统默认每次广播触发时都会创建新的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 创建都会注册一次  
                            }  

                            适配建议‌:遵循生命周期管理原则,避免非预期的重复注册与逻辑执行。

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码