广播 Broadcast 属于 Android 四大组件之一,通过观察者模式,用于实现进程间的异步通信。  
 
广播的实现机制是观察者模式;消息发布/订阅模式的事件驱动模型,消息的生产者发布事件,而使用者订阅感兴趣的事件。Broadcast 机制和 Binder 机制不一样的地方在于:广播的发送者和接收者事先是不需要知道对方的存在的,这也是观察者模式的特点,显而易见的优点是系统的各个组件可以松耦合地组织在一起,所有的广播发送和接收都是通过系统 AMS 来调度的,它充当了广播总线的功能。  
基础 广播实现进程间异步交互:进程间通信时通过 Binder 来实现的,异步通信是通过 Handler 实现。  
广播接收器的分类 
静态注册广播接收器:Manifest-declared receivers 在 AndroidManifest.xml 文件中通过 <receiver> 声明的广播接收器。   
动态注册广播接收器:Context-registered receivers 通过 registerReceiver 注册的广播接收器。 
 
广播的分类 
普通广播 通过 sendBroadcast 发出的广播。   
有序广播 通过 sendOrderedBroadcast 发出的广播;有序广播对应的广播接收器存在优先级关系,优先级越高越先收到广播。有序广播还可以有回调广播接收器,即广播匹配的所有广播接收器处理完毕后,系统会再向广播发送者,发回这个回调。   
粘性广播 通过 sendStickyBroadcast 发出的广播。粘性广播发送后,系统会把代表这个广播的 Intent 保存下来,如果后面在动态注册相同 Action 的广播接收器时,系统就将最后发出的粘性广播重新发送给这个广播接收器。也就是说,尽管广播早就发送处理完毕了,但是后续如果有新注册的广播接收器能匹配这个广播,还是会响应广播事件的。但是粘性广播从 Android 5.0 开始就将相关系统接口全部标注为 @Deprecated。它们不提供安全性(任何人都可以访问它们),没有保护(任何人都可以修改它们)以及许多其他问题。所以 Android 平台已经弃用,本文也不做介绍。   
 
广播的标记 根据发送广播 Intent 设置的标记来区分:  
FLAG_RECEIVER_FOREGROUND 表示广播为前台广播 ,允许接收者以前台的优先级运行,有更短的时间间隔。默认情况下广播都是后台广播    
FLAG_RECEIVER_REPLACE_PENDING 表示新的广播会替换掉那些已存在的相同广播。相同的定义是通过 Intent.filterEquals 方法对两个广播的 Intent 比较,当匹配到相同的,新的广播和对应的接收器会将待发送的广播列表中已存在的替换掉,在列表中保留同样的位置。这个标志通常被粘性广播使用,只保证将最新的广播的值传递给接收器。   
 
广播的 ANR 前台广播的 ANR 时间是 10 秒,后台广播是 60 秒。因为默认为后台广播,所以通常情况下,需要在 60 秒内处理完所有的广播事件。广播的 ANR 只会出现在有序处理的广播队列中(包含有序广播和静态注册的广播接收器匹配的普通广播)中 。  
1 2 3 4 static  final  int  BROADCAST_FG_TIMEOUT = 10 *1000 ;static  final  int  BROADCAST_BG_TIMEOUT = 60 *1000 ;
 
相关类文件 速查表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 framework/base     ./core/java/android/app/ContextImpl.java     ./core/java/android/app/ActivityThread.java     ./core/java/android/app/LoadedApk.java     ./core/java/android/app/BroadcastOptions.java     ./core/java/android/content/IIntentReceiver.aidl     ./core/java/android/content/pm/PackageParser.java     ./core/java/android/content/BroadcastReceiver.java     ./services/core/java/com/android/server/am/BroadcastRecord.java     ./services/core/java/com/android/server/am/ReceiverList.java     ./services/core/java/com/android/server/am/BroadcastFilter.java     ./services/core/java/com/android/server/am/BroadcastQueue.java     ./services/core/java/com/android/server/am/ActivityManagerService.java     ./services/core/java/com/android/server/pm/PackageManagerService.java 
 
类简介 
BroadCastReceiver 广播接收器,用于处理接收的每个广播事件。   
IIntentReceiver 是 AIDL 文件,每个 BroadCastReceiver 都会转换为一个 IIntentReceiver,用来跨进程传递数据。   
LoadedApk.ReceiverDispatcher 广播接收发布器,BroadCastReceiver 都是在这转换为 IIntentReceiver 的。每个动态注册的广播接收器 BroadcastReceiver 都对应一个 LoadedApk.ReceiverDispatcher ,最终都是在这进行响应调用 onReceive 的。   
BroadcastFilter 是 IntentFilter 的子类,广播过滤器,用于匹配广播 Intent;包含广播接收者相关信息,权限等。只有动态注册广播广播接收器会用到。   
ReceiverList 是 ArrayList 的子类,是一个集合用来存储 BroadcastFilter 。记录广播接收器相关信息等,只有动态注册的广播接收器会用到,每个 BroadCastReceiver 对应一个 ReceiverList ,而每个 ReceiverList 可以包含多个 BroadcastFilter ,表示能够监听多个广播。   
BroadcastRecord 继承了 Binder,用来跨进程传递数据。发送的每个广播 Intent ,最后都会对应一个 BroadcastRecord ;它记录了广播的发送时间,发送者,接受者 ,广播携带的数据,回调,所在 BroadcastQueue 等等。   
BroadcastQueue 广播队列,有两个 ArrayList<BroadcastRecord> 用于存储 BroadcastRecord 分别是:mParallelBroadcasts 存储并行处理的广播;mOrderedBroadcasts 存储有序处理的广播。   
ContextImpl 广播发送,广播接收器动态注册的入口。   
ActivityThread 应用主线程,广播发送过程都是由它进入系统进程 AMS,广播接收器响应事件是有系统 AMS 进入它。   
ActivityManagerServiceAMS 系统四大组件大管家,类似广播总线:管理广播接收器的注册,管理广播的发送到匹配的广播接收器中处理。   
PackageParser 包解析类,会从 AndroidManifest.xml 中解析出静态注册的广播接收器。   
PackageManagerServicePMS 系统包管家,负责静态注册广播接收器的存储,查询。   
 
BroadcastFilter 类详解BroadcastFilter 继承了 IntentFilter 类,广播信息过滤器,即动态注册广播接收器时,注册的是哪个广播过滤器。  
源码分析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 final  class  BroadcastFilter  extends  IntentFilter   {         final  ReceiverList receiverList;     final  String packageName;     final  String requiredPermission;     final  int  owningUid;     final  int  owningUserId;     BroadcastFilter(IntentFilter _filter, ReceiverList _receiverList,             String _packageName, String _requiredPermission,              int  _owningUid, int  _userId) {         super (_filter);         receiverList = _receiverList;         packageName = _packageName;         requiredPermission = _requiredPermission;         owningUid = _owningUid;         owningUserId = _userId;     }          public  void  dump (PrintWriter pw, String prefix)   {...}     public  void  dumpBrief (PrintWriter pw, String prefix)   {...}     public  void  dumpInReceiverList (PrintWriter pw, Printer pr,           String prefix)   {...}    void  dumpBroadcastFilterState (PrintWriter pw, String prefix)   {...}     public  String toString ()   {...} 
 
成员变量 
receiverList :当前对象属于哪个接收列表   
packageName :动态注册广播发起者的包名   
requiredPermission :设置发送广播时需要的权限   
owningUid :动态注册广播发起者 Uid   
owningUserId :动态注册广播发起者 UserId    
 
这里简单介绍下 uid, userId 的区别:  
uid 是 Linux 下的概念,表示 Linux 系统下的用户 ID 。   
userId 是 Android 的多用户概念,从 4.2 开始系统支持多用户登录,记录登录用户的 ID ;不支持多用户登录的系统上,这个值是唯一的。多用户支持是在 frameworks/base/core/res/res/values/config.xml 文件中,config_multiuserMaximumUsers 值来决定的。   
 
ReceiverList 类详解ReceiverList 继承了 ArrayList ,本质上是一个数据集合,数据类型为 BroadcastFilter。动态注册广播接收器时,每个广播接收器 BroadCastReceiver 对应一个 ReceiverList ,记录了一系列 BroadcastFilter 的列表,表示这个广播接收器注册了一个或多个广播过滤器。  
源码分析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 final  class  ReceiverList  extends  ArrayList <BroadcastFilter >        implements  IBinder .DeathRecipient   {    final  ActivityManagerService owner;     public  final  IIntentReceiver receiver;     public  final  ProcessRecord app;     public  final  int  pid;     public  final  int  uid;     public  final  int  userId;     BroadcastRecord curBroadcast = null ;     boolean  linkedToDeath = false ;     String stringName;          ReceiverList(ActivityManagerService _owner, ProcessRecord _app,             int  _pid, int  _uid, int  _userId, IIntentReceiver _receiver) {         owner = _owner;         receiver = _receiver;         app = _app;         pid = _pid;         uid = _uid;         userId = _userId;     }          public  boolean  equals (Object o)   {return  this  == o;}     public  int  hashCode ()   {return  System.identityHashCode(this );}          public  void  binderDied ()   {         linkedToDeath = false ;         owner.unregisterReceiver(receiver);     }          void  dumpLocal (PrintWriter pw, String prefix)   {...}     void  dump (PrintWriter pw, String prefix)   {...}     public  String toString ()   {...} 
 
成员变量 
ActivityManagerService owner : AMS 对象   
IIntentReceiver receiver :当前 ReceiverList 对应的 IIntentReceiver   
ProcessRecord app :动态注册广播发起者进程相关信息   
pid :动态注册广播发起者进程 Id   
uid :动态注册广播发起者 uid   
userId :动态注册广播发起者 userId   
BroadcastRecord curBroadcast :动态注册的广播,其详细信息   
linkedToDeath :Binder 通信机制是否断开   
stringName :ReceiverList 转换成的字符串   
 
BroadCastReceiver 类详解BroadCastReceiver 广播接收器,用来处理监听的广播事件。BroadcastReceiver 是抽象类,抽象方法为 onReceive ,注册广播接收器前,需要在其子类中实现。  
PendingResult 类PendingResult 是广播接收器待处理的结果类,是异步结果类;简要介绍下这个类存在的意义: 通常情况下,UI 主线程阻塞超过 5 秒就会产生 ANR,更不用说卡顿现象 UI Jank;所以广播接收器中如果有耗时工作(比如磁盘读写,网络下载等),需要及时切换到后台工作线程中执行;而 PendingResult 就存储了广播处理器接收到广播所有相关信息,将 PendingResult 对象传递到后台工作线程完成广播处理,处理完后需要调用 PendingResult.finish() 通过系统该广播接收器已经处理完毕。 PendingResult 类有两个注意事项:  
PendingResult 类中的状态不是线程安全的 ,使用时将整个对象交给后台工作线程,避免并发竞争,该线程将负责设置结果并最终调用 finish()   
系统中关于广播接收器的 ANR :前台广播接收器允许运行时间大概是 10 秒,后台广播是 60 秒,如果广播处理器没有处理完毕就会产生 ANR 。注意这个过程的计算时间是:从广播分发到广播处理器,直到广播处理器通知系统处理完毕的总时间。即使通过 PendingResult 切换到后台工作线程,直到调用 PendingResult.finish() ,这整个过程都受到了这个 ANR 时间的限制。所以长时间的工作是不能放到 BroadCastReceiver 中来实现的,PendingResult 仅仅是多争取到了几秒钟   
 
PendingResult 类的两个子类PendingResult 类的构造方法是 @hide 隐藏的,通常在 BroadcastReceiver.onReceive() 中调用 goAsync() 返回得到;而实际构造是在其子类中,静态注册广播和动态注册广播对应不同的子类:  
ActivityThread.ReceiverData 对应静态注册广播  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 static  final  class  ReceiverData  extends      BroadcastReceiver .PendingResult   {    public  ReceiverData (Intent intent,int  resultCode,String resultData,          Bundle resultExtras,  boolean  ordered, boolean  sticky,          IBinder token, int  sendingUser)   {        super (resultCode, resultData, resultExtras, TYPE_COMPONENT,              ordered, sticky,token, sendingUser, intent.getFlags());         this .intent = intent;     }     Intent intent;     ActivityInfo info;     CompatibilityInfo compatInfo;     public  String toString ()   {...} } 
 
LoadedApk.ReceiverDispatcher.Args 对应动态注册广播  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 final  class  Args  extends  BroadcastReceiver .PendingResult      implements  Runnable   {    private  Intent mCurIntent;     private  final  boolean  mOrdered;     private  boolean  mDispatched;     public  Args (Intent intent, int  resultCode, String resultData,           Bundle resultExtras, boolean  ordered,          boolean  sticky, int  sendingUser)   {        super (resultCode, resultData, resultExtras,                 mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED,                  ordered, sticky, mIIntentReceiver.asBinder(),                  sendingUser, intent.getFlags());         mCurIntent = intent;         mOrdered = ordered;     }     public  void  run ()   {...} } 
 
 
 
PendingResult 类源码分析PendingResult 对应的广播类型有三种:  
TYPE_COMPONENT :静态注册广播   
TYPE_REGISTERED :动态注册广播   
TYPE_UNREGISTERED :取消广播注册   
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 public  static  class  PendingResult   {         public  static  final  int  TYPE_COMPONENT = 0 ;     public  static  final  int  TYPE_REGISTERED = 1 ;     public  static  final  int  TYPE_UNREGISTERED = 2 ;     final  int  mType;     final  boolean  mOrderedHint;     final  boolean  mInitialStickyHint;     final  IBinder mToken;     final  int  mSendingUser;     final  int  mFlags;     int  mResultCode;     String mResultData;     Bundle mResultExtras;     boolean  mAbortBroadcast;     boolean  mFinished;               public  PendingResult (int  resultCode, String resultData,               Bundle resultExtras, int  type, boolean  ordered,              boolean  sticky, IBinder token, int  userId, int  flags)   {        mResultCode = resultCode;         mResultData = resultData;         mResultExtras = resultExtras;         mType = type;         mOrderedHint = ordered;         mInitialStickyHint = sticky;         mToken = token;         mSendingUser = userId;         mFlags = flags;     }          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)   {...}     public  final  void  setResult (int  code, String data,           Bundle extras)   {...}    public  int  getSendingUserId ()   {...}               public  final  boolean  getAbortBroadcast ()   {return  mAbortBroadcast;}     public  final  void  abortBroadcast ()   {         checkSynchronousHint();         mAbortBroadcast = true ;     }     public  final  void  clearAbortBroadcast ()   {         mAbortBroadcast = false ;     }          public  final  void  finish ()   {         if  (mType == TYPE_COMPONENT) {                          final  IActivityManager mgr = ActivityManager.getService();             if  (QueuedWork.hasPendingWork()) {                                  QueuedWork.queue(new  Runnable() {                     @Override  public  void  run ()   {                         ...                         sendFinished(mgr);                     }                 }, false );             } else  {                 ...                 sendFinished(mgr);             }         } else  if  (mOrderedHint && mType != TYPE_UNREGISTERED) {                          ...             final  IActivityManager mgr = ActivityManager.getService();             sendFinished(mgr);         }     }          public  void  setExtrasClassLoader (ClassLoader cl)   {         if  (mResultExtras != null ) {             mResultExtras.setClassLoader(cl);         }     }          public  void  sendFinished (IActivityManager am)   {       synchronized  (this ) {         if  (mFinished) {             throw  new  IllegalStateException("..." );         }         mFinished = true ;         try  {             if  (mResultExtras != null ) {                 mResultExtras.setAllowFds(false );             }             if  (mOrderedHint) {                 am.finishReceiver(mToken, mResultCode, mResultData,                      mResultExtras, mAbortBroadcast, mFlags);             } else  {                 am.finishReceiver(mToken, 0 , null , null , false , mFlags);             }         } catch  (RemoteException ex) {         }       }     }     ... } 
 
BroadcastReceiver 源码分析1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 public  abstract  class  BroadcastReceiver   {    private  PendingResult mPendingResult;     ...     public  static  class  PendingResult   {...}     public  BroadcastReceiver ()   {}          public  abstract  void  onReceive (Context context, Intent intent)  ;          public  final  PendingResult goAsync ()   {         PendingResult res = mPendingResult;         mPendingResult = null ;         return  res;     }          public  IBinder peekService (Context myContext, Intent service)   {...}               public  final  void  setPendingResult (PendingResult result)   {         mPendingResult = result;     }     public  final  PendingResult getPendingResult ()   {         return  mPendingResult;     }     public  final  String getResultData ()   {         return  mPendingResult != null  ? mPendingResult.mResultData : null ;     }     public  final  void  setResultExtras (Bundle extras)   {         checkSynchronousHint();         mPendingResult.mResultExtras = extras;     }     public  final  void  setResultCode (int  code)   {...}     public  final  int  getResultCode ()   {...}     public  final  Bundle getResultExtras (boolean  makeMap)   {...}     public  final  void  setResult (int  code, String data,           Bundle extras)   {...}    public  int  getSendingUserId ()   {...}               public  final  boolean  getAbortBroadcast ()   {         return  mPendingResult != null  ?              mPendingResult.mAbortBroadcast : false ;     }     public  final  void  abortBroadcast ()   {         checkSynchronousHint();         mPendingResult.mAbortBroadcast = true ;     }     public  final  void  clearAbortBroadcast ()   {         if  (mPendingResult != null ) {             mPendingResult.mAbortBroadcast = false ;         }     }     public  final  boolean  isOrderedBroadcast ()   {...}     public  final  boolean  isInitialStickyBroadcast ()   {...}     ... } 
 
BroadcastReceiver 重要方法BroadcastReceiver 大部分数据存储都是通过 PendingResult 实例来保存的。  
onReceive 抽象方法,子类必须实现;广播接收器处理的入口。   
goAsync 异步广播,返回 PendingResult 实例,进入后台线程处理;处理完毕后必须调用 PendingResult.finish() 结束。   
abortBroadcast 如果广播接收器收到的是有序广播,则终止有序广播继续向下传递。   
 
IIntentReceiver 详解IIntentReceiver 是一个 AIDL 文件,所以 IIntentReceiver 接口继承了 Binder 机制中的 IInterface ,表示服务端拥有的能力或者说能提供的功能。 IIntentReceiver 声明的方法,是在 LoadedApk.ReceiverDispatcher.InnerReceiver 中实现的。IIntentReceiver.aidl 源码如下:  
1 2 3 4 5 6 7 8 9 10 11 12 13 // frameworks/base/core/java/android/content/IIntentReceiver.aidl /**  * System private API for dispatching intent broadcasts.    * This is given to the activity manager as part of registering for   * an intent broadcasts, and is called when it receives intents.  *  * {@hide}  */ oneway interface IIntentReceiver {     void performReceive(in Intent intent, int resultCode, String data,             in Bundle extras, boolean ordered,              boolean sticky, int sendingUser); } 
 
BroadCastReceiver 是系统组件,并不支持跨进程传输,Android Broadcast 机制使用 IIntentReceiver 来进行代替 BroadCastReceiver 来进行跨进程传输。 可以看出 IIntentReceiver 只提供了一个方法 performReceive ,该方法仅仅在动态注册的广播接收器中会触发调用(静态注册广播接收器在 ActivityThread 中通过反射直接调用 onReceive 回调);系统进程 AMS 在分发广播处理事件时,会向注册了广播接收的应用进程调用该方法,最终调用 BroadcastReceiver.onReceive 触发回调。注意:方法使用了 oneway 关键字 ,表示非阻塞调用;即 AMS 进程分发广播事件时,不需要等待每个应用接收者执行完 onReceive 。  
LoadedApk 类LoadedApk 类存储了当前加载的 Apk 相关信息,包括主线程,文件所在路径,类加载器,注册的广播列表,启动的服务列表等等;LoadedApk 类是在每个应用加载初始化进程、主线程时实例化的,每个应用对应一个 LoadedApk 实例。 本文只分析和广播 Broadcast 相关内容,LoadedApk 中存储了当前 Apk 中所有的普通广播接收器 BroadCastReceiver ,即通过 registerReceiver 注册到系统中的广播接收器。 而有序广播中的回调广播接收器 ,即广播发送出去后,等待所有广播接收器处理完毕,最后产生一个回调给广播发送者,作用类似 startActivityForResult 。回调 BroadCastReceiver 不需要通过 registerReceiver 注册到系统中,是以参数的形式在 sendOrderedBroadcast() 发送广播时传递出去,这类广播不会存储到 LoadedApk 中。  
在 ContextImpl 代码中可以看到:LoadedApk 对这两类广播接收器的处理过程:  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 private  Intent registerReceiverInternal (BroadcastReceiver receiver,          int  userId, IntentFilter filter, String broadcastPermission,         Handler scheduler, Context context)   {    IIntentReceiver rd = null ;     if  (receiver != null ) {         if  (mPackageInfo != null  && context != null ) {             if  (scheduler == null ) {                 scheduler = mMainThread.getHandler();             }                                       rd = mPackageInfo.getReceiverDispatcher(                 receiver, context, scheduler,                 mMainThread.getInstrumentation(), true );         } else  {             if  (scheduler == null ) {                 scheduler = mMainThread.getHandler();             }                          rd = new  LoadedApk.ReceiverDispatcher(receiver, context,                  scheduler, null , true ).getIIntentReceiver();         }     }     ... } @Override public  void  sendOrderedBroadcastAsUser (Intent intent, UserHandle user,         String receiverPermission, int  appOp, Bundle options,          BroadcastReceiver resultReceiver, Handler scheduler,          int  initialCode, String initialData, Bundle initialExtras)   {    IIntentReceiver rd = null ;     if  (resultReceiver != null ) {         if  (mPackageInfo != null ) {             if  (scheduler == null ) {                 scheduler = mMainThread.getHandler();             }                                       rd = mPackageInfo.getReceiverDispatcher(                 resultReceiver, getOuterContext(), scheduler,                 mMainThread.getInstrumentation(), false );         } else  {             if  (scheduler == null ) {                 scheduler = mMainThread.getHandler();             }             rd = new  LoadedApk.ReceiverDispatcher(resultReceiver,                  getOuterContext(), scheduler, null , false )                 .getIIntentReceiver();         }     } } 
 
部分源码分析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 public  final  class  LoadedApk   {         private  final  ArrayMap<Context,              ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers         = new  ArrayMap<Context,              ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>();     private  final  ArrayMap<Context,              ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>              mUnregisteredReceivers         = new  ArrayMap<Context,              ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>();     public  IIntentReceiver getReceiverDispatcher (BroadcastReceiver r,              Context context, Handler handler,             Instrumentation instrumentation, boolean  registered)   {      synchronized  (mReceivers) {         LoadedApk.ReceiverDispatcher rd = null ;         ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map=null ;         if  (registered) {             map = mReceivers.get(context);             if  (map != null ) {                 rd = map.get(r);             }         }         if  (rd == null ) {             rd = new  ReceiverDispatcher(r, context, handler,                     instrumentation, registered);                          if  (registered) {                 if  (map == null ) {                     map = new  ArrayMap<BroadcastReceiver,                          LoadedApk.ReceiverDispatcher>();                     mReceivers.put(context, map);                 }                 map.put(r, rd);             }         } else  {             rd.validate(context, handler);         }         rd.mForgotten = false ;         return  rd.getIIntentReceiver();       }     }          public  IIntentReceiver forgetReceiverDispatcher (Context context,              BroadcastReceiver r)   {      synchronized  (mReceivers) {         ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>              map = mReceivers.get(context);         LoadedApk.ReceiverDispatcher rd = null ;         if  (map != null ) {           rd = map.get(r);           if  (rd != null ) {             map.remove(r);             if  (map.size() == 0 ) {                 mReceivers.remove(context);             }             if  (r.getDebugUnregister()) {                 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>                   holder = mUnregisteredReceivers.get(context);                 if  (holder == null ) {                     holder = new  ArrayMap<BroadcastReceiver,                          LoadedApk.ReceiverDispatcher>();                     mUnregisteredReceivers.put(context, holder);                 }                 ...                 holder.put(r, rd);             }             rd.mForgotten = true ;             return  rd.getIIntentReceiver();           }         }         ...         throw  ...       }     }     static  final  class  ReceiverDispatcher   {                  final  static  class  InnerReceiver  extends  IIntentReceiver .Stub   {           ...           InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean  strong) {             mDispatcher=new  WeakReference<LoadedApk.ReceiverDispatcher>(rd);             mStrongRef = strong ? rd : null ;           }                                 @Override            public  void  performReceive (Intent intent, int  resultCode,               String data, Bundle extras, boolean  ordered,              boolean  sticky, int  sendingUser)   {            final  LoadedApk.ReceiverDispatcher rd;             if  (intent == null ) {                 Log.wtf(TAG, "Null intent received" );                 rd = null ;             } else  {                 rd = mDispatcher.get();             }             ...             if  (rd != null ) {                                  rd.performReceive(intent, resultCode, data, extras,                         ordered, sticky, sendingUser);             } else  {                 ...                 IActivityManager mgr = ActivityManagerNative.getDefault();                 try  {                     if  (extras != null ) {                       extras.setAllowFds(false );                     }                                          mgr.finishReceiver(this , resultCode, data,                          extras, false , intent.getFlags());                 } catch  (RemoteException e) {                     throw  e.rethrowFromSystemServer();                 }             }           }         }         final  IIntentReceiver.Stub mIIntentReceiver;         final  BroadcastReceiver mReceiver;         final  Context mContext;         final  Handler mActivityThread;         final  Instrumentation mInstrumentation;         final  boolean  mRegistered;         final  IntentReceiverLeaked mLocation;         RuntimeException mUnregisterLocation;         boolean  mForgotten;                  final  class  Args  extends  BroadcastReceiver .PendingResult               implements  Runnable   {            private  Intent mCurIntent;             private  final  boolean  mOrdered;             private  boolean  mDispatched;             public  Args (Intent intent, int  resultCode, String resultData,                   Bundle resultExtras, boolean  ordered,                  boolean  sticky, int  sendingUser)   {                super (resultCode, resultData, resultExtras,                         mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED,                          ordered, sticky, mIIntentReceiver.asBinder(),                          sendingUser, intent.getFlags());                 mCurIntent = intent;                 mOrdered = ordered;             }                                                    public  void  run ()   {               final  BroadcastReceiver receiver = mReceiver;               final  boolean  ordered = mOrdered;               ...               final  IActivityManager mgr=ActivityManagerNative.getDefault();               ...               try  {                   ClassLoader cl =  mReceiver.getClass().getClassLoader();                   intent.setExtrasClassLoader(cl);                   intent.prepareToEnterProcess();                   setExtrasClassLoader(cl);                   receiver.setPendingResult(this );                   receiver.onReceive(mContext, intent);               } catch  (Exception e) {                   if  (mRegistered && ordered) {                       ...                       sendFinished(mgr);                   }                   ...               }                                             if  (receiver.getPendingResult() != null ) {                   finish();               }               ...             }         }         ReceiverDispatcher(BroadcastReceiver receiver, Context context,                 Handler activityThread, Instrumentation instrumentation,                 boolean  registered) {             if  (activityThread == null ) {                 throw  new  NullPointerException("Handler must not be null" );             }             mIIntentReceiver = new  InnerReceiver(this , !registered);             mReceiver = receiver;             mContext = context;             mActivityThread = activityThread;             mInstrumentation = instrumentation;             mRegistered = registered;             mLocation = new  IntentReceiverLeaked(null );             mLocation.fillInStackTrace();         }         ...         BroadcastReceiver getIntentReceiver ()   {return  mReceiver;}         IIntentReceiver getIIntentReceiver ()   {return  mIIntentReceiver;}         public  void  performReceive (Intent intent, int  resultCode,               String data, Bundle extras, boolean  ordered,             boolean  sticky, int  sendingUser)   {            final  Args args = new  Args(intent, resultCode, data,                  extras, ordered, sticky, sendingUser);             ...                          if  (intent == null  || !mActivityThread.post(args)) {               if  (mRegistered && ordered) {                 IActivityManager mgr=ActivityManagerNative.getDefault();                 if  (ActivityThread.DEBUG_BROADCAST) Slog.i(...);                 args.sendFinished(mgr);               }             }         }     }     ... } 
 
成员变量 
mReceivers :当前 Apk 注册的广播列表   
mUnregisteredReceivers :当前 Apk 取消广播注册的列表   
 
这两个成员变量都是 Map 结构,Key 值都是 Context,Value 仍然是一个 Map 结构:  
Key: Context 每个 Activity 或者每个 Service 注册的广播分开记录,方便快速查找某个 Context 实例注册的所有广播。   
Value: ArrayMap<BroadcastReceiver, ReceiverDispatcher>   
 
BroadcastReceiver 和 ReceiverDispatcher 是一一对应的,每个广播接收器都会对应一个广播接收分发器 。ContextImpl.sendOrderedBroadcast, ContextImpl.registerReceiver 会对每个广播接收器 BroadCastReceiver ,通过 LoadedApk 找到或者生成对应的 ReceiverDispatcher ;在发送有序广播或者注册广播接收器,等到广播接收者开始执行时,AMS 通过 ReceiverDispatcher.InnerReceiver 来触发回调,即调用 BroadCastReceiver.onReceive 。  
ReceiverDispatcher 静态内部类ReceiverDispatcher 是 LoadedApk 的静态内部类,同时它自己还包含两个内部类:  
静态内部类 InnerReceiver 实现了 IIntentReceiver.performReceive 方法,实际最终调用的是外部类 ReceiverDispatcher.performReceive 方法。   
成员内部类 Args 继承了 BroadCastReceiver.PendingResult 类,可以执行部分异步操作;同时实现了 Runnable ,通过传入的 Handler 发布这个任务,并调用 BroadCastReceiver.onReceive ,处理广播接收器回调事件。处理完后,通知系统该广播接收器处理完毕。   
成员变量mRegistered :记录该广播接收器是否通过 registerReceiver 注册的,即是否为动态注册的广播接收器。   
 
ReceiverDispatcher 的几个重要方法:  
getIIntentReceiver :返回广播接收器 BroadCastReceiver 对应的 IIntentReceiver 对象   
performReceive :使用当前线程 Handler 发送 Args 对象并执行;所有动态注册的广播接收器,都是在这里回调 onReceive 方法    
 
广播相关方法 
getReceiverDispatcher 根据广播接收器获取广播接收分发器的 IIntentReceiver ,用于跨进程传递。主要是从 mReceivers 中获取;如果不存在则新建。   
forgetReceiverDispatcher 从 mReceivers 中移除指定回调广播接收器,并放入 mUnregisteredReceivers 中,返回值也是该广播接收器对应的 IIntentReceiver 。   
 
BroadcastRecord 类详解BroadcastRecord 继承了 Binder ,表明该对象作为数据容器,能被跨进程通信。BroadcastRecord 保存了广播发送者相关信息,包含发送者的:包名,进程信息,广播是否有序,请求的权限等等。  
源码分析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 final  class  BroadcastRecord  extends  Binder   {    final  Intent intent;              final  ComponentName targetComp;      final  ProcessRecord callerApp;      final  String callerPackage;      final  int  callingPid;        final  int  callingUid;        final  boolean  ordered;       final  boolean  sticky;             final  boolean  initialSticky;      final  int  userId;            final  String resolvedType;           final  String[] requiredPermissions;      final  int  appOp;        final  BroadcastOptions options;      final  List receivers;        final  int [] delivery;        IIntentReceiver resultTo;      long  enqueueClockTime;       long  dispatchTime;        long  dispatchClockTime;      long  receiverTime;           long  finishTime;             int  resultCode;              String resultData;           Bundle resultExtras;         boolean  resultAbort;         int  nextReceiver;            IBinder receiver;            int  state;     int  anrCount;                int  manifestCount;           int  manifestSkipCount;       BroadcastQueue queue;             static  final  int  IDLE = 0 ;     static  final  int  APP_RECEIVE = 1 ;     static  final  int  CALL_IN_RECEIVE = 2 ;     static  final  int  CALL_DONE_RECEIVE = 3 ;     static  final  int  WAITING_SERVICES = 4 ;          static  final  int  DELIVERY_PENDING = 0 ;     static  final  int  DELIVERY_DELIVERED = 1 ;     static  final  int  DELIVERY_SKIPPED = 2 ;     static  final  int  DELIVERY_TIMEOUT = 3 ;                    BroadcastFilter curFilter;               ProcessRecord curApp;                 ComponentName curComponent;           ActivityInfo curReceiver;        BroadcastRecord(BroadcastQueue _queue,             Intent _intent, ProcessRecord _callerApp,              String _callerPackage, int  _callingPid, int  _callingUid,              String _resolvedType, String[] _requiredPermissions,              int  _appOp, BroadcastOptions _options, List _receivers,              IIntentReceiver _resultTo, int  _resultCode,              String _resultData, Bundle _resultExtras,              boolean  _serialized, boolean  _sticky,              boolean  _initialSticky, int  _userId) {         if  (_intent == null ) {             throw  new  NullPointerException("                  Can't construct with a null intent" );        }         queue = _queue;         intent = _intent;         targetComp = _intent.getComponent();         callerApp = _callerApp;         callerPackage = _callerPackage;         callingPid = _callingPid;         callingUid = _callingUid;         resolvedType = _resolvedType;         requiredPermissions = _requiredPermissions;         appOp = _appOp;         options = _options;         receivers = _receivers;         delivery = new  int [_receivers != null  ? _receivers.size() : 0 ];         resultTo = _resultTo;         resultCode = _resultCode;         resultData = _resultData;         resultExtras = _resultExtras;         ordered = _serialized;         sticky = _sticky;         initialSticky = _initialSticky;         userId = _userId;         nextReceiver = 0 ;         state = IDLE;     }     boolean  cleanupDisabledPackageReceiversLocked (String packageName,           Set<String> filterByClasses, int  userId, boolean  doit)   {        if  ((userId != UserHandle.USER_ALL && this .userId != userId)              || receivers == null ) {             return  false ;         }         boolean  didSomething = false ;         Object o;         for  (int  i = receivers.size() - 1 ; i >= 0 ; i--) {             o = receivers.get(i);             if  (!(o instanceof  ResolveInfo)) {                 continue ;             }             ActivityInfo info = ((ResolveInfo)o).activityInfo;             final  boolean  sameComponent = packageName == null                  || (info.applicationInfo.packageName.equals(packageName)                 && (filterByClasses == null                           || filterByClasses.contains(info.name)));             if  (sameComponent) {                 if  (!doit) {                     return  true ;                 }                 didSomething = true ;                 receivers.remove(i);                 if  (i < nextReceiver) {                     nextReceiver--;                 }             }         }         nextReceiver = Math.min(nextReceiver, receivers.size());         return  didSomething;     }     void  dump (PrintWriter pw, String prefix, SimpleDateFormat sdf)   {...}     public  String toString ()   {...} } 
 
重要成员变量 
Intent intent :广播发送时的 Intent   
ComponentName targetComp :广播发送者组件名称   
ProcessRecord callerApp :广播发送者进程记录   
String callerPackage :广播发送者包名   
callingPid :广播发送者 Pid   
callingUid :广播发送者 Uid   
userId :广播发送者 userId   
ordered :广播是否有序发送 
sticky :广播是否为粘性广播   
initialSticky :广播是否一开始就设置为粘性广播   
resolvedType :Intent 的类型   
String[] requiredPermissions :广播发送者拥有的广播权限   
appOp :广播对应的应用管理权限   
BroadcastOptions options :广播发送者设定的选项   
List receivers :广播接收者列表,特别需要注意的是:它包含了两种类型数据 ResolveInfo, BroadcastFilter,分别对应静态注册广播接收器和动态注册广播接收器,取出时需要做类型判断   
int[] delivery :每个广播接收者的投递状态,状态分为四种   
IIntentReceiver resultTo :有序广播中回调的广播接收器,它也是有序广播的最后一个接收者   
enqueueClockTime :广播进入队列的时间   
dispatchTime :开始分派广播的开机时间   
dispatchClockTime :开始分派广播的系统绝对时间   
receiverTime :广播接收者接收到的时间   
finishTime :广播接收者处理完广播的完成时间   
resultCode :广播处理完毕的结果码   
resultData :广播处理完毕的简单数据   
resultExtras :广播处理完毕的复杂数据   
resultAbort :广播是否被终止   
int nextReceiver :下一个广播接收者索引   
IBinder receiver :广播当前接收者   
int state :广播的当前状态,状态分为五种   
anrCount :当前广播出现的 ANR 次数   
manifestCount :分发给静态注册广播接收者的次数   
manifestSkipCount :分发给静态注册广播接收者跳过的次数   
BroadcastQueue queue :处理当前广播所在队列   
BroadcastFilter curFilter :处理广播时当前广播过滤器   
ProcessRecord curApp :广播当前接收者的进程信息   
ComponentName curComponent :广播当前接收者的组件信息   
ActivityInfo curReceiver :广播当前接收者的信息   
 
cleanupDisabledPackageReceiversLocked 方法BroadcastRecord 中只有一个包内可见的方法 cleanupDisabledPackageReceiversLocked ,该方法功能是从 List receivers 清理掉已经取消注册的广播注册接收者。  
BroadcastQueue 类详解BroadcastQueue 用来保存系统和应用发出的广播信息;通常使用两个广播队列 BroadcastQueue :一个用来保存前台广播,一个用来保存后台广播;而每个广播队列 BroadcastQueue 包含两个列表:一个用来并行处理;一个用来有序处理。  
重要成员变量 
ArrayList<BroadcastRecord> mParallelBroadcasts 存储并行处理的广播:首先它是普通广播,其次这些广播匹配的广播接收器必须是动态注册的。   
ArrayList<BroadcastRecord> mOrderedBroadcasts 存储有序处理的广播:包含有序广播和普通广播(匹配的广播接收器时静态注册的 )。   
mTimeoutPeriod 广播接收器 ANR 超时时间阀值。前台广播是 10 秒,后台广播是 60 秒。   
 
BroadcastHandler 类BroadcastHandler 是成员内部类,用来处理下一条广播,或者处理广播超时 ANR 。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 static  final  int  BROADCAST_INTENT_MSG =     ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG; static  final  int  BROADCAST_TIMEOUT_MSG =     ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG + 1 ; final  BroadcastHandler mHandler;private  final  class  BroadcastHandler  extends  Handler   {    public  BroadcastHandler (Looper looper)   {         super (looper, null , true );     }     @Override      public  void  handleMessage (Message msg)   {         switch  (msg.what) {             case  BROADCAST_INTENT_MSG: {                 if  (DEBUG_BROADCAST) Slog.v(                         TAG_BROADCAST, "Received BROADCAST_INTENT_MSG" );                 processNextBroadcast(true );             } break ;             case  BROADCAST_TIMEOUT_MSG: {                 synchronized  (mService) {                     broadcastTimeoutLocked(true );                 }             } break ;         }     } } 
 
AppNotResponding 类AppNotResponding 成员内部类,广播接收器处理广播事件时发生 ANR 。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 private  final  class  AppNotResponding  implements  Runnable   {    private  final  ProcessRecord mApp;     private  final  String mAnnotation;     public  AppNotResponding (ProcessRecord app, String annotation)   {         mApp = app;         mAnnotation = annotation;     }     @Override      public  void  run ()   {         mService.mAppErrors.appNotResponding(mApp,              null , null , false , mAnnotation);     } } 
 
静态注册广播接收器流程分析 静态注册的广播接收器,又称为 Manifest 文件声明广播接收器,是在 PMS 扫描 AndroidManifest.xml 信息时解析的;所有静态注册的广播接收器,统一由 PMS 保存,广播在发送过程中,查找匹配的静态注册广播接收器也是在 PMS 中查询。  
流程图 
PackageParser.parseBaseApplication 详解PackageParser 主要用于详细解析包内相关信息,而 parseBaseApplication 主要解析 AndroidManifest.xml ,将每个 TAG 都解析并保存,其中静态注册的广播接收器存储到 receivers 中,而 PMS 会根据每个包解析的数据,保存整个系统全部的静态注册广播接收器(当然也保存其他 Activity, Services, ContentProvider 等信息)。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 public  final  ArrayList<Activity> receivers = new  ArrayList<Activity>(0 );private  boolean  parseBaseApplication (Package owner, Resources res,         XmlResourceParser parser, int  flags, String[] outError)     ...     while  ((type = parser.next() ) ! = XmlPullParser.END_DOCUMENT            && (type != XmlPullParser.END_TAG                  || parser.getDepth() > innerDepth)) {         if  (type == XmlPullParser.END_TAG              || type == XmlPullParser.TEXT) {             continue ;         }         String tagName = parser.getName();         if  (tagName.equals("activity" )) {             ...         } else  if  (tagName.equals("receiver" )) {                          Activity a = parseActivity(owner, res, parser, flags,                      outError, cachedArgs, true , false );             if  (a == null ) {                 mParseError =                      PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;                 return  false ;             }             owner.receivers.add(a);         }         ...     }     ... } 
 
PMS 静态注册广播接收器PMS 在调用完 PackageParser.parsePackage 解析完指定包名信息后,将存储在 PackageParser.Package.receivers 的静态广播接收器信息,再保存到 PMS.mReceivers 中,方便后续全局查询。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 final  ActivityIntentResolver mReceivers =        new  ActivityIntentResolver(); private  void  commitPackageSettings (PackageParser.Package pkg,          PackageSetting pkgSetting, UserHandle user, int  scanFlags,          boolean  chatty)  throws  PackageManagerException  {    final  String pkgName = pkg.packageName;     ...          N = pkg.receivers.size();     r = null ;     for  (i=0 ; i<N; i++) {         PackageParser.Activity a = pkg.receivers.get(i);         a.info.processName=fixProcessName(pkg.applicationInfo.processName,                 a.info.processName);                  mReceivers.addActivity(a, "receiver" );         if  (chatty) {             if  (r == null ) {                 r = new  StringBuilder(256 );             } else  {                 r.append(' ' );             }             r.append(a.info.name);         }     }     if  (r != null ) {         if  (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: "  + r);     }     ... } 
 
PMS 查询静态注册广播接收器AMS 在发送广播时,会从 PMS 中查询匹配的静态广播接收器;PMS.queryIntentReceiversInternal 根据广播 Intent ,从 mReceivers 中查询匹配的 ResolveInfo,而 ResolveInfo.activityInfo 存储了对应的广播接收器。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 private  @NonNull  List<ResolveInfo> queryIntentReceiversInternal (          Intent intent, String resolvedType, int  flags, int  userId,          boolean  allowDynamicSplits)   {        ...     synchronized  (mPackages) {         String pkgName = intent.getPackage();         if  (pkgName == null ) {                          final  List<ResolveInfo> result = mReceivers.queryIntent(                     intent, resolvedType, flags, userId);             return  applyPostResolutionFilter(result, instantAppPkgName,                     allowDynamicSplits, callingUid, userId);         }         final  PackageParser.Package pkg = mPackages.get(pkgName);         if  (pkg != null ) {                      final  List<ResolveInfo> result=mReceivers.queryIntentForPackage(                   intent, resolvedType, flags, pkg.receivers, userId);           return  applyPostResolutionFilter(result, instantAppPkgName,                  allowDynamicSplits, callingUid, userId);         }         return  Collections.emptyList();     } } final  class  ActivityIntentResolver   extends  IntentResolver <        PackageParser .ActivityIntentInfo , ResolveInfo >  {    public  List<ResolveInfo> queryIntent (Intent intent,               String resolvedType, boolean  defaultOnly, int  userId)   {        if  (!sUserManager.exists(userId)) return  null ;         mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0 );         return  super .queryIntent(intent, resolvedType,              defaultOnly, userId);     }     public  List<ResolveInfo> queryIntent (Intent intent,               String resolvedType, int  flags, int  userId)   {        if  (!sUserManager.exists(userId)) return  null ;         mFlags = flags;         return  super .queryIntent(intent, resolvedType,                 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0 ,                 userId);     }          public  List<ResolveInfo> queryIntentForPackage (Intent intent,               String resolvedType, int  flags,              ArrayList<PackageParser.Activity> packageActivities,              int  userId)   {...}    ... } 
 
protected-broadcast 受保护的广播在 AndroidManifest.xml 中声明的 protected-broadcast 受保护广播 ACTION ,表示它们只能被有系统权限的广播接收器接收。在 PackageParser.Package.protectedBroadcasts 中保存,同时 PMS.mProtectedBroadcasts 会做系统全局保存, AMS 发送广播时会查询 PMS 做权限检查,如果没有权限则不会分发给该广播接收器。  
动态注册/取消广播接收器流程分析 流程图 
动态注册 ContextImpl/LoadedApk 动态注册时统一由 ContextImpl.registerReceiverInternal 向系统注册广播接收器。这个过程主要功能:  
将 BroadCastReceiver 转换为对应的 IIntentReceiver ,用于跨进程通信   
LoadedApk.getReceiverDispatcher 会将当前 Apk 注册的每个广播接收器保存到 mReceivers 中;如果是有序广播的回调广播接收器则不保存   
向 AMS 中注册 IIntentReceiver   
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 private  Intent registerReceiverInternal (BroadcastReceiver receiver,          int  userId, IntentFilter filter, String broadcastPermission,         Handler scheduler, Context context, int  flags)   {    IIntentReceiver rd = null ;     if  (receiver != null ) {         if  (mPackageInfo != null  && context != null ) {             if  (scheduler == null ) {                 scheduler = mMainThread.getHandler();             }                          rd = mPackageInfo.getReceiverDispatcher(                 receiver, context, scheduler,                 mMainThread.getInstrumentation(), true );         } else  {             if  (scheduler == null ) {                 scheduler = mMainThread.getHandler();             }             rd = new  LoadedApk.ReceiverDispatcher(receiver, context,                     scheduler, null , true ).getIIntentReceiver();         }     }     try  {                  final  Intent intent = ActivityManager.getService()                 .registerReceiver(mMainThread.getApplicationThread(),                  mBasePackageName, rd, filter, broadcastPermission,                  userId, flags);         if  (intent != null ) {             intent.setExtrasClassLoader(getClassLoader());             intent.prepareToEnterProcess();         }         return  intent;     } catch  (RemoteException e) {         throw  e.rethrowFromSystemServer();     } } public  IIntentReceiver getReceiverDispatcher (BroadcastReceiver r,         Context context, Handler handler,         Instrumentation instrumentation, boolean  registered)   {    synchronized  (mReceivers) {         LoadedApk.ReceiverDispatcher rd = null ;         ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>             map = null ;         if  (registered) {             map = mReceivers.get(context);             if  (map != null ) {                 rd = map.get(r);             }         }         if  (rd == null ) {                          rd = new  ReceiverDispatcher(r, context, handler,                     instrumentation, registered);             if  (registered) {                                           if  (map == null ) {                     map = new  ArrayMap<BroadcastReceiver,                          LoadedApk.ReceiverDispatcher>();                     mReceivers.put(context, map);                 }                 map.put(r, rd);             }         } else  {             rd.validate(context, handler);         }         rd.mForgotten = false ;         return  rd.getIIntentReceiver();     } } 
 
动态注册 AMS 广播接收器动态注册时,广播接收器的相关信息保存在 AMS 中:  
mRegisteredReceivers 保存所有动态注册的广播接收器对应的 ReceiverList 。mRegisteredReceivers 并没有太多作用,注册保存信息,取消注册时从这里删除。   
mReceiverResolver 保存所有所有动态注册广播接收器时对应的广播过滤器 BroadcastFilter 。广播发送过程中,会根据 Intent 从 mReceiverResolver 中查找 BroadcastFilter ;每个 BroadcastFilter 都保存了它所属的 ReceiverList ;而 ReceiverList 保存了 BroadCastReceiver 对应的 IIntentReceiver ;动态注册广播接收器事件处理时,使用 IIntentReceiver 处理 onReceive 回调。   
 
主要功能:  
获取动态注册广播接收器,应用进程相关信息   
处理粘性广播事件   
BroadCastReceiver 生成对应的 ReceiverList 和 BroadcastFilter   
将 ReceiverList 添加到 mRegisteredReceivers 中   
将 BroadcastFilter 添加到 mReceiverResolver 中   
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public  Intent registerReceiver (IApplicationThread caller,          String callerPackage, IIntentReceiver receiver,          IntentFilter filter, String permission, int  userId,         int  flags)   {    enforceNotIsolatedCaller("registerReceiver" );     ArrayList<Intent> stickyIntents = null ;     ProcessRecord callerApp = null ;     ...     int  callingUid;     int  callingPid;     ...     Intent sticky = allSticky != null  ? allSticky.get(0 ) : null ;     ...     synchronized  (this ) {         if  (callerApp != null  && (callerApp.thread == null                  || callerApp.thread.asBinder() != caller.asBinder())) {                          return  null ;         }         ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());         if  (rl == null ) {             rl = new  ReceiverList(this , callerApp, callingPid,                      callingUid, userId, receiver);             if  (rl.app != null ) {                 rl.app.receivers.add(rl);             } else  {                 ...             }             mRegisteredReceivers.put(receiver.asBinder(), rl);         } else  ...         BroadcastFilter bf = new  BroadcastFilter(filter, rl,                  callerPackage, permission, callingUid, userId,                 instantApp, visibleToInstantApps);         rl.add(bf);         ...         mReceiverResolver.addFilter(bf);         ...         return  sticky;     } } 
 
取消注册 ContextImpl/LoadedApk 取消注册时统一由 ContextImpl.unregisterReceiver 向系统取消注册广播接收器。这个过程主要功能:  
将 BroadCastReceiver 转换为对应的 IIntentReceiver ,用于跨进程通信   
LoadedApk.forgetReceiverDispatcher 会将当前需要取消注册的广播接收器,从 mReceivers 中移除;如果需要调试,会同时将它加入 mUnregisteredReceivers 中   
向 AMS 中取消注册 IIntentReceiver   
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 @Override public  void  unregisterReceiver (BroadcastReceiver receiver)   {    if  (mPackageInfo != null ) {                           IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(                 getOuterContext(), receiver);         try  {                          ActivityManager.getService().unregisterReceiver(rd);         } catch  (RemoteException e) {             throw  e.rethrowFromSystemServer();         }     } else  {         throw  new  RuntimeException("Not supported in system context" );     } } public  IIntentReceiver forgetReceiverDispatcher (Context context,         BroadcastReceiver r)   {    synchronized  (mReceivers) {         ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>              map = mReceivers.get(context);         LoadedApk.ReceiverDispatcher rd = null ;         if  (map != null ) {             rd = map.get(r);             if  (rd != null ) {                 map.remove(r);                                  if  (map.size() == 0 ) {                     mReceivers.remove(context);                 }                 if  (r.getDebugUnregister()) {                     ...                                          mUnregisteredReceivers.put(context, holder);                     ...                 }                 rd.mForgotten = true ;                 return  rd.getIIntentReceiver();             }         }         ...     } } 
 
取消注册 AMS 广播接收器取消注册时,从 AMS 中移除对应的数据,主要功能为:  
从 mRegisteredReceivers 中移除 ReceiverList   
从 mReceiverResolver 中移除 ReceiverList 中所有的 BroadcastFilter   
如果还存在没有处理完的广播接收器,触发 BroadcastQueue.processNextBroadcast 继续处理   
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public  void  unregisterReceiver (IIntentReceiver receiver)   {    ...     final  long  origId = Binder.clearCallingIdentity();     try  {       boolean  doTrim = false ;       synchronized (this ) {         ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());         if  (rl != null ) {           final  BroadcastRecord r = rl.curBroadcast;                      if  (r != null  && r == r.queue.getMatchingOrderedReceiver(r)) {               final  boolean  doNext = r.queue.finishReceiverLocked(                       r, r.resultCode, r.resultData, r.resultExtras,                       r.resultAbort, false );               if  (doNext) {                   doTrim = true ;                   r.queue.processNextBroadcast(false );               }           }           if  (rl.app != null ) {               rl.app.receivers.remove(rl);           }                      removeReceiverLocked(rl);           ...         }       }         ...     } finally  {         Binder.restoreCallingIdentity(origId);     } } void  removeReceiverLocked (ReceiverList rl)   {    mRegisteredReceivers.remove(rl.receiver.asBinder());     for  (int  i = rl.size() - 1 ; i >= 0 ; i--) {         mReceiverResolver.removeFilter(rl.get(i));     } } 
 
广播发送流程分析 先回顾下基础概念,广播的类型:  
普通广播:通过 sendBroadcast 发送的广播   
有序广播:通过 sendOrderedBroadcast 发送的广播   
 
系统对广播响应并处理的方式分为:  
并行处理 广播存储位置:BroadcastQueue.mParallelBroadcasts ;并行处理的广播为:普通广播,且它对应的广播接收器一定是动态注册的。   
有序处理 广播存储位置:BroadcastQueue.mOrderedBroadcasts ;有序处理的广播为:有序广播和普通广播(对应的广播接收器是静态注册的)。mOrderedBroadcasts 中处理普通广播(对应的广播接收器时静态注册的)非常费解,初看代码时很容易搞错,存储逻辑是在 AMS 调度时决定的。   
 
流程图 
广播发送过程,从广播发送所在应用进程进入系统进程 Context -> AMS -> BroadcastQueue   
 
广播发送过程,从系统进程进入广播接收器应用所在进程 BroadcastQueue -> ActivityThread -> BroadCastReceiver.onReceive   
 
ContextImpl.sendBroadcast 发送普通广播ContextImpl 对于普通广播并不做特别处理,比较简单,直接将 Intent 和广播发送应用相关信息传递给 AMS ,进入系统来处理分发流程。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Override public  void  sendBroadcast (Intent intent)   {    warnIfCallingFromSystemProcess();     String resolvedType=intent.resolveTypeIfNeeded(getContentResolver());     try  {         intent.prepareToLeaveProcess(this );                  ActivityManager.getService().broadcastIntent(                 mMainThread.getApplicationThread(), intent, resolvedType,                  null , Activity.RESULT_OK, null , null , null ,                  AppOpsManager.OP_NONE, null , false , false , getUserId());     } catch  (RemoteException e) {         throw  e.rethrowFromSystemServer();     } } 
 
ContextImpl.sendOrderedBroadcast 发送有序广播有序广播支持广播接收器回调,所以进入系统 AMS 处理前,会先将 BroadCastReceiver 转换为 IIntentReceiver ,回调广播接收器在 LoadedApk 中不做保存。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 void  sendOrderedBroadcast (Intent intent, String receiverPermission,         int  appOp, BroadcastReceiver resultReceiver,         Handler scheduler, int  initialCode, String initialData,         Bundle initialExtras, Bundle options)   {    warnIfCallingFromSystemProcess();     IIntentReceiver rd = null ;     if  (resultReceiver != null ) {         if  (mPackageInfo != null ) {             if  (scheduler == null ) {                 scheduler = mMainThread.getHandler();             }                                       rd = mPackageInfo.getReceiverDispatcher(                 resultReceiver, getOuterContext(), scheduler,                 mMainThread.getInstrumentation(), false );         } else  {             if  (scheduler == null ) {                 scheduler = mMainThread.getHandler();             }             rd = new  LoadedApk.ReceiverDispatcher(                     resultReceiver, getOuterContext(), scheduler,                      null , false ).getIIntentReceiver();         }     }     String resolvedType=intent.resolveTypeIfNeeded(getContentResolver());     String[] receiverPermissions = receiverPermission == null  ? null              : new  String[] {receiverPermission};     try  {         intent.prepareToLeaveProcess(this );                  ActivityManager.getService().broadcastIntent(             mMainThread.getApplicationThread(), intent, resolvedType, rd,             initialCode, initialData, initialExtras, receiverPermissions,              appOp, options, true , false , getUserId());     } catch  (RemoteException e) {         throw  e.rethrowFromSystemServer();     } } 
 
AMS.broadcastIntentLocked 广播发送解析不管是普通广播还是有序广播,在 AMS 中都是进入了 broadcastIntentLocked(Intent, ...) 方法来调度处理的。这个方法中会处理很多系统级广播,比如 Intent.ACTION_PACKAGE_ADDED, Intent.ACTION_PACKAGE_REMOVED, Intent.ACTION_TIME_CHANGED 等等,在 AMS 做预处理或者直接处理完毕。该方法主要功能:  
各种权限检查   
系统广播处理   
收集该广播匹配的所有动态注册广播接收器   
收集该广播匹配的所有静态注册广播接收器   
将广播对应的广播记录存入广播队列(如果是有序广播,会按照优先级先排序再存入)   
 
代码分析(代码有简化和调整位置)如下:  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 final  int  broadcastIntentLocked (ProcessRecord callerApp,         String callerPackage, Intent intent, String resolvedType,         IIntentReceiver resultTo, int  resultCode, String resultData,         Bundle resultExtras, String[] requiredPermissions, int  appOp,          Bundle bOptions, boolean  ordered, boolean  sticky,          int  callingPid, int  callingUid, int  userId)   {    intent = new  Intent(intent);          ...     List receivers = null ;     List<BroadcastFilter> registeredReceivers = null ;          receivers = collectReceiverComponents(intent, resolvedType,                      callingUid, users);     ...          registeredReceivers = mReceiverResolver.queryIntent(intent,                      resolvedType, false  , users[i]);     int  NR = registeredReceivers != null  ? registeredReceivers.size() : 0 ;               if  (!ordered && NR > 0 ) {         ...         final  BroadcastQueue queue = broadcastQueueForIntent(intent);         BroadcastRecord r = new  BroadcastRecord(queue, intent, callerApp,                 callerPackage, callingPid, callingUid, callerInstantApp,                  resolvedType, requiredPermissions, appOp, brOptions,                  registeredReceivers, resultTo, resultCode, resultData,                  resultExtras, ordered, sticky, false , userId);         if  (DEBUG_BROADCAST)              Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast "  + r);         final  boolean  replaced = replacePending                 && (queue.replaceParallelBroadcastLocked(r) != null );                  if  (!replaced) {                          queue.enqueueParallelBroadcastLocked(r);             queue.scheduleBroadcastsLocked();         }         registeredReceivers = null ;         NR = 0 ;     }                              int  ir = 0 ;          ...     while  (ir < NR) {         if  (receivers == null ) {             receivers = new  ArrayList();         }         receivers.add(registeredReceivers.get(ir));         ir++;     }                    if  ((receivers != null  && receivers.size() > 0 )             || resultTo != null ) {         BroadcastQueue queue = broadcastQueueForIntent(intent);         BroadcastRecord r = new  BroadcastRecord(queue, intent, callerApp,                 callerPackage, callingPid, callingUid, callerInstantApp,                  resolvedType, requiredPermissions, appOp, brOptions,                  receivers, resultTo, resultCode, resultData,                  resultExtras, ordered, sticky, false , userId);         ...                  queue.enqueueOrderedBroadcastLocked(r);         queue.scheduleBroadcastsLocked();     }     ...     return  ActivityManager.BROADCAST_SUCCESS; } 
 
BroadcastQueue.processNextBroadcast 广播发送解析不管是并行处理还是有序处理,在 BroadcastQueue 中都是进入 processNextBroadcast(boolean fromMsg) 方法处理的。该方法主要功能:  
并行处理的广播接收器,一次全部处理完   
有序广播处理完毕后,处理回调广播接收器   
各种权限检查   
调用 deliverToRegisteredReceiverLocked 处理所有动态注册的广播接收器   
如果是静态广播接收器,开启对应的应用进程   
调用 processCurBroadcastLocked 处理所有静态注册的广播接收器   
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 final  void  processNextBroadcast (boolean  fromMsg)   {    BroadcastRecord r = null ;     ...               while  (mParallelBroadcasts.size() > 0 ) {         r = mParallelBroadcasts.remove(0 );         ...         final  int  N = r.receivers.size();         for  (int  i=0 ; i<N; i++) {             Object target = r.receivers.get(i);             ...                          deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target,                  false , i);         }         ...     }               boolean  looped = false ;       do  {                  if  (mOrderedBroadcasts.size() == 0 ) {             ...             return ;         }         r = mOrderedBroadcasts.get(0 );         boolean  forceReceive = false ;         int  numReceivers = (r.receivers != null ) ? r.receivers.size() : 0 ;         ...         if  (r.receivers == null  || r.nextReceiver >= numReceivers                 || r.resultAbort || forceReceive) {                                                    if  (r.resultTo != null ) {                 try  {                     if  (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,                         "Finishing broadcast ["  + mQueueName + "] "                          + r.intent.getAction() + " app="  + r.callerApp);                     performReceiveLocked(r.callerApp, r.resultTo,                         new  Intent(r.intent), r.resultCode, r.resultData,                         r.resultExtras, false , false , r.userId);                     r.resultTo = null ;                 } catch  (RemoteException e) {                     ...                 }             }             ...             if  (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,                     "Finished with ordered broadcast "  + r);             ...             mOrderedBroadcasts.remove(0 );             r = null ;             looped = true ;             continue ;         }     } while  (r == null );          int  recIdx = r.nextReceiver++;     ...     final  Object nextReceiver = r.receivers.get(recIdx);               if  (nextReceiver instanceof  BroadcastFilter) {                           BroadcastFilter filter = (BroadcastFilter)nextReceiver;         if  (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,                 "Delivering ordered ["                  + mQueueName + "] to registered "                  + filter + ": "  + r);         deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);         ...         return ;     }                    ResolveInfo info =         (ResolveInfo)nextReceiver;     ComponentName component = new  ComponentName(             info.activityInfo.applicationInfo.packageName,             info.activityInfo.name);     ...     String targetProcess = info.activityInfo.processName;     ProcessRecord app = mService.getProcessRecordLocked(targetProcess,             info.activityInfo.applicationInfo.uid, false );     ...               if  (app != null  && app.thread != null  && !app.killed) {         try  {             app.addPackage(info.activityInfo.packageName,                     info.activityInfo.applicationInfo.versionCode,                      mService.mProcessStats);             processCurBroadcastLocked(r, app);             return ;         } catch  (RuntimeException e) {             ...             return ;         }     }               if  (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,             "Need to start app ["              + mQueueName + "] "  + targetProcess + " for broadcast "  + r);     if  ((r.curApp=mService.startProcessLocked(targetProcess,             info.activityInfo.applicationInfo, true ,             r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,             "broadcast" , r.curComponent,             (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0 ,              false , false ))                     == null ) {                  ...         return ;     }               mPendingBroadcast = r;     mPendingBroadcastRecvIndex = recIdx;     ... } 
 
deliverToRegisteredReceiverLocked 方法解析BroadcastQueue.deliverToRegisteredReceiverLocked 专门用来处理动态注册的广播接收器,最终是在 performReceiveLocked 方法中调用了 ActivityThread.scheduleRegisteredReceiver ,进入广播接收器所在进程处理具体的回调 onReceive。这个阶段主要功能:  
各种权限检查   
添加完善广播记录   
跨进程进入广播接收器所在应用进程,调用 onReceive   
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 private  void  deliverToRegisteredReceiverLocked (BroadcastRecord r,         BroadcastFilter filter, boolean  ordered, int  index)   {    boolean  skip = false ;          ...          if  (skip) {         r.delivery[index] = BroadcastRecord.DELIVERY_SKIPPED;         return ;     }                         if  (ordered) {         r.receiver = filter.receiverList.receiver.asBinder();         r.curFilter = filter;         filter.receiverList.curBroadcast = r;         r.state = BroadcastRecord.CALL_IN_RECEIVE;         if  (filter.receiverList.app != null ) {                                                                              r.curApp = filter.receiverList.app;             filter.receiverList.app.curReceivers.add(r);             mService.updateOomAdjLocked(r.curApp, true );         }     }     try  {         if  (DEBUG_BROADCAST_LIGHT) Slog.i(TAG_BROADCAST,                 "Delivering to "  + filter + " : "  + r);         if  (filter.receiverList.app != null               && filter.receiverList.app.inFullBackup) {             ...         } else  {                          performReceiveLocked(filter.receiverList.app,                      filter.receiverList.receiver, new  Intent(r.intent),                     r.resultCode, r.resultData, r.resultExtras,                      r.ordered, r.initialSticky, r.userId);         }         if  (ordered) {             r.state = BroadcastRecord.CALL_DONE_RECEIVE;         }     } catch  (RemoteException e) {         Slog.w(TAG, "Failure sending broadcast "  + r.intent, e);         ...     } } void  performReceiveLocked (ProcessRecord app, IIntentReceiver receiver,         Intent intent, int  resultCode, String data, Bundle extras,         boolean  ordered, boolean  sticky, int  sendingUser)          throws  RemoteException  {              if  (app != null ) {         if  (app.thread != null ) {                                       try  {                                  app.thread.scheduleRegisteredReceiver(receiver, intent,                         resultCode, data, extras, ordered, sticky,                          sendingUser, app.repProcState);             } catch  (RemoteException ex) {                 ...             }         } else  {                          throw  new  RemoteException("app.thread must not be null" );         }     } else  {         receiver.performReceive(intent, resultCode, data, extras,                  ordered, sticky, sendingUser);     } } 
 
ActivityThread.scheduleRegisteredReceiver 方法解析每个应用的主线程中 ActivityThread.scheduleRegisteredReceiver 来执行广播处理事件,performReceive 对应的是 LoadedApk.ReceiverDispatcher.InnerReceiver.performReceive 方法。  
1 2 3 4 5 6 7 8 public  void  scheduleRegisteredReceiver (IIntentReceiver receiver,          Intent intent, int  resultCode, String dataStr,          Bundle extras, boolean  ordered, boolean  sticky,          int  sendingUser, int  processState)  throws  RemoteException  {    updateProcessState(processState, false );     receiver.performReceive(intent, resultCode, dataStr, extras,              ordered, sticky, sendingUser); } 
 
processCurBroadcastLocked 方法解析BroadcastQueue.processCurBroadcastLocked 专门处理静态注册的广播接收器。该方法主要功能:  
将 BroadCastReceiver 子类存储到 intent 中   
跨进程进入静态广播接收器所在进程,通过反射调用 onReceive   
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 private  final  void  processCurBroadcastLocked (BroadcastRecord r,         ProcessRecord app)  throws  RemoteException  {    if  (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,             "Process cur broadcast "  + r + " for app "  + app);     ...     r.receiver = app.thread.asBinder();     r.curApp = app;     app.curReceivers.add(r);     app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);     mService.updateLruProcessLocked(app, false , null );     mService.updateOomAdjLocked();               r.intent.setComponent(r.curComponent);          boolean  started = false ;     try  {         ...                  app.thread.scheduleReceiver(new  Intent(r.intent),                  r.curReceiver,                 mService.compatibilityInfoForPackageLocked(                 r.curReceiver.applicationInfo),                 r.resultCode, r.resultData, r.resultExtras,                  r.ordered, r.userId, app.repProcState);         if  (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,                 "Process cur broadcast "  + r                  + " DELIVERED for app "  + app);         started = true ;     } finally  {         if  (!started) {             ...         }     } } 
 
ActivityThread.scheduleReceiver 方法解析ActivityThread.scheduleReceiver 处理静态注册的广播接收器,从 intent 中获取具体的广播接收器子类组件名,在 handleReceiver 中使用反射技术生成对应的实例对象,并调用其 onReceive 方法。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 public  final  void  scheduleReceiver (Intent intent, ActivityInfo info,         CompatibilityInfo compatInfo, int  resultCode, String data,          Bundle extras, boolean  sync, int  sendingUser, int  processState)  {    updateProcessState(processState, false );          ReceiverData r = new  ReceiverData(intent, resultCode, data, extras,             sync, false , mAppThread.asBinder(), sendingUser);     r.info = info;     r.compatInfo = compatInfo;     sendMessage(H.RECEIVER, r); } private  void  handleReceiver (ReceiverData data)   {    ...          String component = data.intent.getComponent().getClassName();     LoadedApk packageInfo = getPackageInfoNoCheck(             data.info.applicationInfo, data.compatInfo);     IActivityManager mgr = ActivityManager.getService();     Application app;     BroadcastReceiver receiver;     ContextImpl context;     try  {         app = packageInfo.makeApplication(false , mInstrumentation);         context = (ContextImpl) app.getBaseContext();         if  (data.info.splitName != null ) {             context = (ContextImpl) context.                 createContextForSplit(data.info.splitName);         }                  java.lang.ClassLoader cl = context.getClassLoader();         data.intent.setExtrasClassLoader(cl);         data.intent.prepareToEnterProcess();         data.setExtrasClassLoader(cl);         receiver = (BroadcastReceiver)cl.loadClass(component)                     .newInstance();     } catch  (Exception e) {         if  (DEBUG_BROADCAST) Slog.i(...);         data.sendFinished(mgr);         throw  new  RuntimeException(...);     }     try  {         ...                  sCurrentBroadcastIntent.set(data.intent);         receiver.setPendingResult(data);         receiver.onReceive(context.getReceiverRestrictedContext(),                 data.intent);     } catch  (Exception e) {         if  (DEBUG_BROADCAST) Slog.i(...);         data.sendFinished(mgr);         if  (!mInstrumentation.onException(receiver, e)) {             throw  new  RuntimeException(...);         }     } finally  {         sCurrentBroadcastIntent.set(null );     }     if  (receiver.getPendingResult() != null ) {         data.finish();     } } 
 
AMS.finishReceiver 结束广播所有的广播接收器处理完毕后,最终会调用系统 ActivityManagerService.finishReceiver 结束整个流程。结束流程前会再次检查确认,是否还有广播接收器没有处理完(静态注册的广播接收器,如果应用没有启动,会先启动应用进程),存在的话就触发 BroadcastQueue.processNextBroadcast 继续分发。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public  void  finishReceiver (IBinder who, int  resultCode,          String resultData, Bundle resultExtras,          boolean  resultAbort, int  flags)   {    ...     final  long  origId = Binder.clearCallingIdentity();     try  {         boolean  doNext = false ;         BroadcastRecord r;                           synchronized (this ) {             BroadcastQueue queue =                      (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0                      ? mFgBroadcastQueue : mBgBroadcastQueue;             r = queue.getMatchingOrderedReceiver(who);             if  (r != null ) {                 doNext = r.queue.finishReceiverLocked(r, resultCode,                     resultData, resultExtras, resultAbort, true );             }         }         if  (doNext) {             r.queue.processNextBroadcast(false );         }         trimApplications();     } finally  {         Binder.restoreCallingIdentity(origId);     } } 
 
广播 ANR processNextBroadcast 中可以看到,广播的 ANR 只会出现在有序处理的广播队列 mOrderedBroadcasts 中,也就是普通广播匹配的动态注册的广播接收器不会出现 ANR 。  
setBroadcastTimeoutLocked :设置广播超时延时消息   
broadcastTimeoutLocked :当广播接收者等待时间过长,触发 ANR 机制   
cancelBroadcastTimeoutLocked :当广播正常执行完毕清除   
 
超时时间计算方式:从队列中取出有效广播开始计时,直到所有的广播接收器处理完毕,才取消计时。 示例:发送一个有序广播,AndroidManifest.xml 中静态注册的广播接收器和一个动态注册的广播接收器都能匹配到,同时有序广播带有回调广播接收器,也就是说该广播一共会有三个 BroadCastReceiver.onReceive 响应处理。看对应的 Log 文件:  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 // 1. AMS.broadcastIntent 发送广播 06-17*.163: D/XMT(1485): ***********AMS: broadcastIntent########## 06-17*.163: V/ActivityManager(1485): Broadcast: Intent { act=broadcast.service.order flg=0x10 (has extras) } ordered=true userid=0 06-17*.163: V/ActivityManager(1485): Enqueueing broadcast: broadcast.service.order replacePending=false // 2. 广播是后台广播 06-17*.163: I/ActivityManager(1485): Broadcast intent Intent { act=broadcast.service.order flg=0x10 (has extras) } on background queue // 3. 存入 BroadcastQueue.mOrderedBroadcasts 中 06-17*.163: V/ActivityManager(1485): Enqueueing ordered broadcast BroadcastRecord{46a4f31 u0 broadcast.service.order}: prev had 0 06-17*.163: I/ActivityManager(1485): Enqueueing broadcast broadcast.service.order 06-17*.164: V/BroadcastQueue(1485): Schedule broadcasts [background]: current=false 06-17*.164: V/BroadcastQueue(1485): Received BROADCAST_INTENT_MSG // 4. 进入 BroadcastQueue.processNextBroadcast 处理具体的广播, mOrderedBroadcasts 中只有一个广播 06-17*.164: V/BroadcastQueue(1485): processNextBroadcast [background]: 0 parallel broadcasts, 1 ordered broadcasts // 5. 从 mOrderedBroadcasts 中取出有效广播   06-17*.164: V/BroadcastQueue(1485): Processing ordered broadcast [background] BroadcastRecord{46a4f31 u0 broadcast.service.order} // 6. 有序处理广播 ANR 开始计时 06-17*.164: V/BroadcastQueue(1485): Submitting BROADCAST_TIMEOUT_MSG [background] for BroadcastRecord{46a4f31 u0 broadcast.service.order} at 40095097 // 7. deliverToRegisteredReceiverLocked 开始处理动态注册的广播接收器 06-17*.164: V/BroadcastQueue(1485): Delivering ordered [background] to registered BroadcastFilter{d73ca43 u0 ReceiverList{a3cf3f2 9397 com.ymzs.androidbasicknowledge:broadcast/10076/u0 remote:550afd}}: BroadcastRecord{46a4f31 u0 broadcast.service.order} 06-17*.165: I/BroadcastQueue(1485): Delivering to BroadcastFilter{d73ca43 u0 ReceiverList{a3cf3f2 9397 com.ymzs.androidbasicknowledge:broadcast/10076/u0 remote:550afd}} : BroadcastRecord{46a4f31 u0 broadcast.service.order} // 8. 动态注册的广播接收器响应 onReceive 06-17*.168: D/XMT:BroadcastService(9397): mActionOrderBroadcastReceiver: onReceive = order // 9. 动态注册广播接收器响应完毕后,调用 finishReceiver 结束广播流程 06-17*.169: V/ActivityManager(1485): Finish receiver: android.os.BinderProxy@550afd // 10. 结束广播流程时,发现 mOrderedBroadcasts 中还有广播没有处理完毕 // 触发 processNextBroadcast 继续分发广播 06-17*.169: V/BroadcastQueue(1485): processNextBroadcast [background]: 0 parallel broadcasts, 1 ordered broadcasts // 11. processCurBroadcastLocked 开始处理静态注册的广播接收器 06-17*.169: V/BroadcastQueue(1485): Process cur broadcast BroadcastRecord{46a4f31 u0 broadcast.service.order} for app ProcessRecord{64ad616 9368:com.ymzs.androidbasicknowledge/u0a76} 06-17*.170: V/BroadcastQueue(1485): Delivering to component ComponentInfo{com.ymzs.androidbasicknowledge/com.ymzs.androidbasicknowledge.ipc.BroadcastReceiverMy}: BroadcastRecord{46a4f31 u0 broadcast.service.order} 06-17*.171: V/BroadcastQueue(1485): Process cur broadcast BroadcastRecord{46a4f31 u0 broadcast.service.order} DELIVERED for app ProcessRecord{64ad616 9368:com.ymzs.androidbasicknowledge/u0a76} // 12. 静态注册的广播接收器响应 onReceive 06-17*.175: D/XMT:BroadcastReceiverMy(9368): BroadcastReceiverMy: onReceive = order // 13. 静态注册广播接收器响应完毕后,调用 finishReceiver 结束广播流程 06-17*.176: V/ActivityManager(1485): Finish receiver: android.os.BinderProxy@61c0b97 // 14. 结束广播流程时,发现 mOrderedBroadcasts 中还有广播没有处理完毕 // 触发 processNextBroadcast 继续分发广播,处理有序广播的回调 06-17*.176: V/BroadcastQueue(1485): processNextBroadcast [background]: 0 parallel broadcasts, 1 ordered broadcasts // 15. 有序广播的回调广播接收器响应 onReceive 06-17*.176: D/XMT:BroadcastActivity(9397): mResultBroadcastReceiver: onReceive = order 06-17*.176: I/BroadcastQueue(1485): Finishing broadcast [background] broadcast.service.order app=ProcessRecord{64ad616 9368:com.ymzs.androidbasicknowledge/u0a76} // 17. 有序处理广播 ANR 计时取消 06-17*.177: V/BroadcastQueue(1485): Cancelling BROADCAST_TIMEOUT_MSG 06-17*.177: V/BroadcastQueue(1485): Finished with ordered broadcast BroadcastRecord{46a4f31 u0 broadcast.service.order} 
 
示例 静态注册广播接收器 
BroadCastReceiver 子类文件  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public  class  BroadcastReceiverMy  extends  BroadcastReceiver   {    private  static  final  String TAG = "XMT:BroadcastReceiverMy" ;     @Override      public  void  onReceive (Context context, Intent intent)   {         if  (intent != null ){                                                                                           String value = intent.getStringExtra("key" );             Log.d(TAG, "BroadcastReceiverMy: onReceive = "  + value);         }     } } 
 
在 AndroidManifest.xml 中声明  1 2 3 4 5 6 7 8 9 10 11 <receiver     android:name=".ipc.BroadcastReceiverMy"      android:enabled="true"      android:exported="true" >     <intent-filter>         <action android:name="broadcast.service.normal"></action>     </intent-filter>     <intent-filter>         <action android:name="broadcast.service.order"></action>     </intent-filter> </receiver> 
 
 
 
动态注册广播接收器 动态注册和取消注册广播必须在生命周期中成对出现,比如在 onCreate/onDestroy, onResume/onPause, onStart/onStop 对应出现。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 private  boolean  registeredOrder;private  boolean  registeredNormal;private  BroadcastReceiver mActionOrderBroadcastReceiver     = new  BroadcastReceiver() {     @Override      public  void  onReceive (Context context, Intent intent)   {         if  (intent != null ) {             String value = intent.getStringExtra("key" );             Log.d(TAG, "mActionOrderBroadcastReceiver: onReceive = "                  + value);             setResultData("mActionOrderBroadcastReceiver:From Service" );         }     } }; private  BroadcastReceiver mActionNormalBroadcastReceiver     = new  BroadcastReceiver() {     @Override      public  void  onReceive (Context context, Intent intent)   {         if  (intent != null ){             String value = intent.getStringExtra("key" );             Log.d(TAG, "mActionNormalBroadcastReceiver: onReceive = "                  + value);         }     } }; @Override public  void  onCreate ()   {    super .onCreate();     Log.d(TAG, "onCreate: " );     IntentFilter intentFilter =          new  IntentFilter(BroadcastActivity.BROADCAST_ACTION_ORDER);     registerReceiver(mActionOrderBroadcastReceiver, intentFilter);     registeredOrder = true ;     intentFilter =          new  IntentFilter(BroadcastActivity.BROADCAST_ACTION_NORMAL);     registerReceiver(mActionNormalBroadcastReceiver, intentFilter);     registeredNormal = true ; } @Override public  int  onStartCommand (Intent intent, int  flags, int  startId)   {    doLongWork();     return  super .onStartCommand(intent, flags, startId); } @Override public  void  onDestroy ()   {    super .onDestroy();     Log.d(TAG, "onDestroy: " );     if  (registeredOrder){         unregisterReceiver(mActionOrderBroadcastReceiver);         mActionOrderBroadcastReceiver = null ;         registeredOrder = false ;     }     if  (registeredNormal){         unregisterReceiver(mActionNormalBroadcastReceiver);         mActionNormalBroadcastReceiver = null ;         registeredNormal = false ;     } } 
 
广播发送 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 private  void  sendOrderBroadcast ()  {    Log.d(TAG, "sendOrderBroadcast: " );     Intent intent = new  Intent(BROADCAST_ACTION_ORDER);     intent.putExtra("key" , "order" );     sendOrderedBroadcast(intent, null , mResultBroadcastReceiver,          null , 0 , null , null ); } private  BroadcastReceiver mResultBroadcastReceiver     = new  BroadcastReceiver(){     @Override      public  void  onReceive (Context context, Intent intent)   {         String result = getResultData();         mTvResultReceiver.setText(result);     } }; private  void  sendNormalBroadcast ()  {    Log.d(TAG, "sendNormalBroadcast: sendNormalBroadcast" );     Intent intent = new  Intent(BROADCAST_ACTION_NORMAL);     intent.putExtra("key" , "normal" );     sendBroadcast(intent); } 
 
小结 广播接收器静态注册过程 静态注册的广播接收器,是开机时 PMS 启动后解析扫描所有包时注册的,保存在每个包的 PackageParser.Package.receivers 中,系统 PMS.mReceivers 会全局保存所有静态注册的广播接收器。 AMS 中并不会保存静态注册的广播接收器信息,而是直接向 PMS 中查询。    
AMS 中存储的广播相关信息
广播队列:前台广播队列 mFgBroadcastQueue 和后台广播队列 mBgBroadcastQueue   
广播接收器哈希表 mRegisteredReceivers:所有动态注册的广播接收器   
广播过滤器符号表 mReceiverResolver:所有动态注册的广播过滤器 
 
1 2 3 4 5 6 BroadcastQueue mFgBroadcastQueue; BroadcastQueue mBgBroadcastQueue; final  HashMap<IBinder, ReceiverList> mRegisteredReceivers = new  HashMap<>();final  IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver    = new  IntentResolver<BroadcastFilter, BroadcastFilter>() {...} 
 
权限检查 广播在发送的过程中,会有大量的权限检查,比如 AMS.broadcastIntentLocked, BroadcastQueue.processNextBroadcast, BroadcastQueue.deliverToRegisteredReceiverLocked 都会反复做权限检查。  
广播接收器优先级 数字越大表示优先级越高,接收有序广播时优先级高的先接收到。  
静态注册广播接收器  1 2 3 4 5 <receiver  android:name =".smsReceiver" >      <intent-filter  android:priority ="1000" >       <action  android:name ="android.provider.Telephony.SMS_RECEIVED" />       </intent-filter >  </receiver > 
 
动态注册广播接收器  1 2 3 4 IntentFilter intentFilter = new  IntentFilter(     "android.provider.Telephony.SMS_RECEIVED" ); intentFilter.setPriority(1000 ); registerReceiver(broadcastReceiver, intentFilter); 
 
 
 
广播接收器响应 广播接收器回调 onReceive 触发响应的位置  
静态注册的广播接收器ActivityThread.handleReceiver 中使用反射,触发 onReceive 方法。静态注册的广播接收器并不会对应 ReceiverDispatcher 。   
动态注册的广播接收器 动态注册的广播接收器对应一个 ReceiverDispatcher ,通过它找到 LoadedApk.Args ,在 Runnable.run 中触发 onReceive 方法。   
 
前后台广播及 ANR 广播发送时,通过 Intent 是否设置 FLAG_RECEIVER_FOREGROUND 来区分,如果设置了表示前台广播,对应 ANR 超时为 10 秒;默认为后台广播,对应超时为 60 秒。 广播的 ANR 是会出现在有序处理广播队列中,在 BroadcastQueue.processNextBroadcast 中计算的,从有序队列 mOrderedBroadcasts 取出有效广播后开始计时,直到有序广播匹配的所有广播接收器包括有序广播的回调广播接收器,全部处理完毕才会取消计时。具体可以看“广播 ANR” 这一节的 Log 分析。 注意:如果广播接收器的 onReceive 是在主线程中处理,同时还会受到 Activity 超时 5 秒产生 ANR 的限制!也就是说等不到 60 秒,可能 Activity 就出现 ANR 了。如果 onReceive 有耗时任务,请新开线程处理。  
有序广播 
可以被终止 优先级高的广播接收者接收到后,可以通过 abortBroadcast 来终止继续向下传递广播。   
可以有回调 BroadCastReceiver 广播接收器回调,发送有序广播时,可以同时指定一个 BroadCastReceiver 回调;当有序广播全部被执行完后,会触发这个回调。也就是说有序广播,在顺序接收过程中,每个广播接收者都可以在回调 BroadCastReceiver 中向发送者写回数据。   
 
广播发送过程 
整个广播发送及响应过程都是异步的,大量使用 Handler 异步处理   
源码中可以看到大量 synchronized 关键字,而且大多使用 AMS 作为对象锁,所以系统处理广播的过程有大量同步过程   
 
并行处理和有序处理 
mParallelBroadcasts 广播队列 存储的广播为普通广播(对应的广播接收器是动态注册的),该队列的所有广播都是并行处理的,在 processNextBroadcast 中一次全部处理完。   
mOrderedBroadcasts 广播队列 存储的广播为有序广播和普通广播(对应的广播接收器时静态注册的)该队列的所有广播都是有序处理的,在 processNextBroadcast 中从队列中取出一个有效广播,处理完一个广播接收器后,会触发 AMS.finishReceiver 结束整个广播过程。但是 finishReceiver 方法每次都会调用 BroadcastQueue.finishReceiverLocked 检查 mOrderedBroadcasts 是否全部处理完毕。如果没有,调用 processNextBroadcast 继续从有序队列中取出广播处理。具体可以参考“广播 ANR” 中的 Log 分析。   
 
进程和线程间交互 
Handler 线程间异步通信   
LocalBroadcastManager 同一个应用相同进程内异步通信,本质上仍然是通过 Handler 实现的   
BroadCastReceiver 进程间异步通信,不同应用不同进程间的通信,通过系统广播总线统一管理广播,用户使用很简单方便   
Messenger 进程间异步通信,相同应用不同进程间的通信,常用于 Activity, Service 不在同一进程时使用   
AIDL 进程间同步通信   
 
参考文档