广播是什么?

定义

  1. 广泛运用在应用程序之间传输信息的机制。
  2. 发送广播内容是一个 Intent。

广播的使用场景

  1. 同一 app 内有多个进程的不同组件之间的消息通信。
  2. 不同 app 之间的组件之间消息的通信。

广播的分类

无序广播

context.sendBroadcast(Intent)方法发送的广播,不可被拦截,当然发送的数据,接收者是不能进行修改的。

有序广播

context.sendOrderBroadcast(Intent)方法发送的广播,可被拦截,而且接收者是可以修改其中要发送的数据,修改和添加都是可以的,这就意味着优先接收者对数据修改之后,下一个接收者接受的数据是上一个接收者已经修改了的。

本地广播

localBroadcastManager.sendBroadcast(Intent),只在 app 内传播。 本地广播的发送和注册广播接收器都需要使用到 LocalBroadcastManager 类,如下所示为本地广播的发送和本地广播接收器注册的代码:

1
2
3
4
5
public static void sendLocalBroadcast(Context context,String action){
Intent intent = new Intent(action);
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
localBroadcastManager.sendBroadcast(intent);
}
1
2
3
4
5
IntentFilter intentFilter = new IntentFilter();
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
intentFilter.addAction(new BroadcastUtil().action_next);
nasbr = new NextAndStartBroadcastReceiver();
localBroadcastManager.registerReceiver(nasbr, intentFilter);//注册本地广

广播接收器

广播接收器是专门用来接收广播信息的,它可分为静态注册和动态注册:

静态注册

动态注册

广播接收器的优缺点

动态注册的广播接收器可以自由地控制注册与注销,在灵活性方面有很大优势,但是它也存在着一个缺点,即必须要在程序启动之后才能接收到广播,因为注册的逻辑是写在 onCreate()方法中的。那么有没有广播能在程序未启动的情况下就能接收到广播呢?静态注册的广播接收器就可以做到。

那些系统发送的广播有哪些?

广播源码

系统广播的源码角度分析

  1. 自定义广播接收者 BroadcastReceiver,并且重写 onReceiver()方法。
  2. 通过 Binder 机制向 AMS(Activity Manager Service)进行注册。
  3. 广播发送者通过 Binder 机制向 AMS 发送广播。
  4. AMS 查找符合条件(IntentFilter/Permission 等)的 BroadcastReceiver,将广播发送到相应的 BroadcastReceiver(一般情况下是 Activity)的消息队列中。
  5. 消息循环执行拿到此广播,回调 BroadcastReceiver 中的 onReceiver()方法。

本地广播的源码角度分析

相比于系统广播而言,本地广播更加安全,更加高效,以下是本地广播的特点以及内
部的实现机制:

特点:

  1. 使用它发送的广播将只在自身 app 内传播,因此你不必担心泄漏隐私的数据。
  2. 其他 app 无法对你的 app 发送该广播,因此你的 app 根本不可能收到非自身 app 发送的该广播,因此你不必担心有安全漏洞可以利用。
  3. 比系统广播更加高效。

内部实现机制:

  1. LocalBroadcast 高效的原因:因为它内部是通过 Handler 实现的,它的 sendBroadcast()方法含义并非和系统的 sendBroadcast()一样,它的 sendBroadcast()方法其实就是通过Handler 发送了一个 Message 而已。
  2. LocalBroadcast 安全的原因:既然它是通过 Handler 实现广播发送的,那么相比系统广播通过 Binder 机制实现那肯定更加高效,同时使用 Handler 来实现,别的 app 无法向我们应用发送该广播,而我们 app 内部发送的广播也不会离开我们的 app。LocalBroadcast 内部协作主要是靠两个 Map 集合:mReceivers 和 mActions,当然还有一个 List 集合 mPendingBroadcasts,这个主要存储待接收的广播对象。