Android中的广播

广播

Android中的广播(Broadcast)是一种允许应用之间、应用与系统之间异步通信的机制。它提供了一种灵活、高效的方式来传递事件通知和数据。

广播的分类

标准广播(Normal Broadcast)

  • 特点异步执行的广播,广播一经发出,所有广播接收器几乎都在同一时间接收此广播,没有先后顺序。这种广播效率高,但无法拦截。
  • 使用场景:适用于不需要广播接收顺序或不需要拦截的场景,如系统启动时发送广播通知各个应用程序进行初始化操作,或网络状态变化时通知各个应用程序更新UI等

有序广播(Normal Broadcast)

  • 特点同步执行的广播,广播发出后,同一时刻只有一个广播接收器接收此广播,当这个广播接收器处理完逻辑之后,广播才会继续传播。此外,广播接收器接收后可拦截,使排在后面的广播接收器无法接受此广播。
  • 使用场景:适合需要按照特定顺序处理广播的场景,如权限检查、拦截特定广播等

广播的注册方式

广播接收器可以自由地对自己感兴趣的广播进行注册,这样当有相应的广播发出时,广播接收器就能够收到该广播,并在内部处理相应的逻辑。

静态注册

主要通过在AndroidManifest.xml文件中进行声明来实现。以下是具体的实现步骤:

  1. 打开AndroidManifest.xml文件:这个文件位于Android项目的app/src/main目录下。
  2. 添加组件注册信息
  • 对于Activity,添加<activity>标签,并指定android:name属性为Activity的全路径类名。同时,可以通过<intent-filter>标签定义该Activity的启动条件,如设置<action><category>
  • 对于Service,添加<service>标签,并指定android:name属性为Service的全路径类名。

  • 对于BroadcastReceiver,添加<receiver>标签,并指定android:name属性为BroadcastReceiver的全路径类名。同样,可以通过<intent-filter>标签定义该Receiver将接收的动作。

    <uses-permission>标签又加入了一条权限。android.permission.RECEIVE_BOOT _COMPLETED

  1. 保存并编译项目:确保AndroidManifest.xml文件无误后,保存并编译项目,Android系统会在应用安装时根据这些信息注册相应的组件。

  2. 快速打开方式

  • 使用Android Studio 提供的快捷方式来创建-个广播接收器,包→New→Other→Broadcast Receiver,BootCompleteReceiver,Exported 属性表示是否允许这个广播接收器接收本程序以外的广播,Enabled属性表示是否启用这个广播接收器。勾选这两个属性,点击 Finish 完成创建。

动态注册

动态注册主要在运行时通过代码实现,常用于需要在特定条件下才接收广播的场景。以下是具体的实现步骤:

  1. 创建BroadcastReceiver的子类:实现onReceive(Context context, Intent intent)方法,用于处理接收到的广播。
  2. 创建IntentFilter对象:通过IntentFilter对象指定要接收的广播类型,可以使用addAction方法添加多个动作。
  3. 注册BroadcastReceiver:在Activity或Service的onCreate等生命周期方法中,调用registerReceiver方法注册BroadcastReceiver。该方法接受两个参数:BroadcastReceiver实例和IntentFilter对象。
  4. 取消注册BroadcastReceiver:在Activity或Service的onDestroy等生命周期方法中,调用unregisterReceiver方法取消注册BroadcastReceiver,以防止内存泄漏。

发送自定义广播

发送标准广播

  1. 定义Intent:首先,你需要定义一个Intent对象,并通过setAction()方法设置一个自定义的action字符串,用于标识这个广播。
  2. 发送广播:然后,你可以通过调用ContextsendBroadcast(Intent intent)方法来发送这个广播。

发送有序广播

有序广播会按照接收器在AndroidManifest.xml中声明的顺序(通过android:priority属性)或动态注册时指定的顺序来依次传递。每个接收器都可以对广播进行处理,并且可以选择是否将广播继续传递给下一个接收器。

  1. 定义Intent:首先,你需要定义一个Intent对象,并通过setAction()方法设置一个自定义的action字符串,用于标识这个广播。
  2. 发送广播:然后,你可以通过调用Context的send0rderedBroadcast()方法来发送这个广播。第一个参数仍然是Intent,第二个参数是一个与权限相关的字符串,这里传入null 就行了。

附加;

  • 广播优先级:有序广播会按照接收器在AndroidManifest.xml中声明的顺序(通过android:priority属性)或动态注册时指定的顺序来依次传递。
  • 广播截断:onReceive()方法中调用了 abortBroadcast()方法,就表示将这条广播截断。

系统广播和本地广播

系统广播(System Broadcasts)

系统广播是由Android系统发出的,用于通知应用系统事件的发生,如设备启动完成、电池电量变化、网络连接状态变化等。

实现步骤:
  1. 定义广播接收器(BroadcastReceiver)
    创建一个继承自BroadcastReceiver的类,并重写onReceive(Context context, Intent intent)方法,在该方法中处理接收到的广播。

    public class MyBroadcastReceiver extends BroadcastReceiver {  
        @Override  
        public void onReceive(Context context, Intent intent) {  
            // 处理接收到的广播  
        }  
    }
    
  2. 注册广播接收器

    • 静态注册:AndroidManifest.xml文件中注册,这种方式接收的广播不受应用是否运行的影响。

      <receiver android:name=".MyBroadcastReceiver">  
          <intent-filter>  
              <action android:name="android.intent.action.BOOT_COMPLETED" />  
          </intent-filter>  
      </receiver>
      
    • 动态注册:在代码中注册,这种方式通常用于接收那些不需要在应用未运行时接收的广播,或者需要根据条件动态注册/注销的广播。

      IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);  
      MyBroadcastReceiver receiver = new MyBroadcastReceiver();  
      registerReceiver(receiver, filter);
      
  3. 处理广播
    onReceive方法中根据Intent对象中的信息进行处理。

注意事项:
  • 静态注册的广播接收器需要在AndroidManifest.xml中声明,并可能需要特定的权限。但需要注意,从Android 8.0(API 级别 26)开始,对静态注册的系统广播接收进行了更严格的限制,许多隐式广播不再被允许
  • 动态注册的广播接收器需要在应用运行时注册,并在不再需要时注销,以避免内存泄漏。

本地广播(Local Broadcasts)

本地广播是Android提供的一种更安全、更高效的广播机制,它只允许应用内部进行通信,避免了应用间的干扰和潜在的安全问题。

实现步骤:(动态注册很像)
  1. 定义广播接收器(BroadcastReceiver)
    与系统广播相同,首先定义一个继承自BroadcastReceiver的类。

  2. 发送本地广播
    使用LocalBroadcastManager来发送广播,而不是直接使用Context.sendBroadcast()

    java复制代码
    
    LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
    
  3. 注册本地广播接收器
    同样使用LocalBroadcastManager来注册广播接收器,而不是在AndroidManifest.xml中注册。

    java复制代码
    
    LocalBroadcastManager.getInstance(context).registerReceiver(receiver, filter);
    
  4. 处理广播
    onReceive方法中处理接收到的广播。

  5. 注销广播接收器
    在不再需要接收广播时,使用LocalBroadcastManager注销广播接收器。

    java复制代码
    
    LocalBroadcastManager.getInstance(context).unregisterReceiver(receiver);
    
注意事项:
  • 本地广播只能在应用内部使用,不能跨应用通信。无法静态注册。
  • 使用本地广播时,不需要在AndroidManifest.xml中声明广播接收器。
  • 本地广播的效率更高,因为它避免了系统级别的广播分发,减少了不必要的资源消耗。

思考

静态注册和动态注册的区别

静态注册

  • AndroidManifest.xml文件中进行注册,组件在应用程序安装时即被系统所知。
  • 应用程序不运行时也能接收到广播。
  • 需要定义intent-filter来指定组件希望接收的广播类型。
  • 由于注册在清单文件中,所以一旦注册就固定不变,除非重新修改清单文件并重新安装应用。

动态注册

  • 在应用程序运行时通过代码注册,通常在ActivityonCreate方法或Service的启动方法中进行。
  • 可以根据需要动态地注册和注销组件,灵活性更高。
  • 不需要在AndroidManifest.xml中声明intent-filter,但在注册时需要指定IntentFilter对象。
  • 当应用被关闭或组件被销毁时,如果未注销广播接收器,可能会导致内存泄漏。

静态注册的组件有哪些特点

  • 自动性:一旦应用安装,组件即被系统识别并准备接收广播/Intent。
  • 全局性:即使在应用未运行时,也能接收到符合条件的广播。
  • 权限控制:对于某些敏感的广播,系统可能要求应用具有特定的权限才能接收。
  • 固定性:注册信息写在清单文件中,不易被更改(除非重新安装应用)。

为什么要在Activity或Service的onDestroy方法中取消注册BroadcastReceiver

  • 如果在ActivityServiceonDestroy方法中不取消注册BroadcastReceiver,那么在ActivityService被销毁后,BroadcastReceiver仍然保留在内存中,并且可能继续接收广播。这会导致内存泄漏,因为BroadcastReceiver会持有对其上下文(Context)的引用,而这个上下文(ActivityService)本身已经不再需要并且应该被垃圾回收。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值