type
status
date
slug
summary
tags
category
icon
password

广播实现机制

先思考几个问题:
  • 广播注册到了什么地方?
  • 当发送广播的时候,是谁在分发广播?
  • BroadcastReceiver是如何接收到广播的?

广播注册

从 Activity或者Context的registerReceiver()方法一路查看调用,可知最终注册实际上是在ActivityManagerService里进行的.
注册到了一个成员变量中:
这里的ReceiverList实际上就是BroadcastFilter(IntentFilter的继承类)的ArrayList封装.
而IBinder则是IItentReceiver,是一个AIDL定义的接口,在 LoadedApkReceiverDispatcher中有相应的代理实现类IntentReceiver.
BroadcastReceiver会被传递并封装到IItentReceiver中.
这样上面说的map其实也就清楚了: key ~= BroadcastReceiver, value ~= List<IntentFilter>

广播发送

sendBroadcast(Intent intent)出发,最终依然是由ActivityManagerService#broadcastIntent()方法处理的.
这里大概几个步骤:
  1. 检查Intent对象合法性,是否有问题,然后封装一些中间类传递数据
  1. 检查Intent是否为一些系统级的广播ACTION,然后发出Handler消息做对应的处理
  1. sticky广播相关的逻辑
  1. 查询处理静态注册可以接收的reciever
  1. 通过IntentResolver查询符合要求的BroadcastFilter
  1. 获取对应的BroadcastQueue对象(有三种,前台,后台,卸载),并将对应的Intent封装到BroadcastRecord中,并添加到BroadcastQueue中(queue.enqueueOrderedBroadcastLocked(r);)
  1. 开始BroadcastQueue的调度,这里需要注意的是分为两种调度:
      • 并行: enqueueParallelBroadcastLocked(r)
      • 串行: enqueueOrderedBroadcastLocked(r)

广播分发/调度

BroadcastReceiver中有:
可以看到这里其实就是通过Handler Message机制进行调度的.
调度的逻辑里会区分当前进程是否已经正在运行,广播是串行还是并行的,然后进入各自的调度逻辑.
这里挑一个串行的调度逻辑分析下,并行的逻辑也是大同小异的.
串行分发逻辑最终都会通过oneway binder调用IIntentReceiverperformReceive()方法去执行;
正如前面所说,在LoadedApk.ReceiverDispathcer  中有:
getRunnable()方法中有:
显而易见的,又是通过反射获取Receiver的对象并调用onReceive()方法.
执行完毕或者失败,发送执行完毕消息.

广播类型

  • 普通广播/有序广播/粘性广播
    • 普通广播随机顺序发送广播,有序广播串行发送数据,粘性广播不安全已被废弃
  • 串行/并行广播
    • 静态广播接收器不管广播是否为并行,都按照串行处理
      动态广播接收器遇到串行广播则按照串行处理,遇到并行广播则按照并行处理.

接收顺序问题

  • 广播发送时本身的优先级(比如有序广播)
  • 动态广播先于静态广播接收器收到广播

本地广播

主要是调用LocalBroadcastManager去使用,与系统广播的各种机制其实没什么关系,只是利用了一下BroadcastReceiver这个抽象类而已,其本质就是观察者模式 + Handler消息传递.因此在应用内传递效率颇高.
而且它的实现在支持包中,并不在源码中,目前是在androidx的支持包中.
看一段代码就明白了:

参考文章

  1. https://developer.android.com/guide/components/broadcasts
Android中的HandlerKotlin中的CoroutineScope
Loading...