Android5.0 广播机制源码分析

1、概述      广播机制其实本质上它是一种组件间的通信方式。它的发送和接受者事先,不需要知道对方的存在。这样可以使各个组件轻松的耦合在一块。便于扩展,其实这就是一种生产消费模式。(消息 发布/订阅模式的事件驱动模型)消息的生产者发布事件,而使用者订阅感兴趣的事件。在广播机制中,ActivityManagerServices扮演者广播中心的角色,非常的关键。负责和系统所有广播的注册和发布操作。和系统中的组件通过Binder进行通信。

2、注册过程分析。    注册过程分为动态注册和静态注册。    2.1、动态注册的receiver。     

  
   
     IntentFilter filter = new IntentFilter("com.zy.test");
   
   
     //android.util.Log.d("zy_rec","receiverfour getPriority"+filter.getPriority());// zy 
   
   
     filter.setPriority(999);
   
   
     MainActivity.this.registerReceiver(mreceiver, filter);
   
  

    
    此时是在当前应用的进程当中,最终调用到ContextImpl中的相应的方法,然后调用到registerReceiverInternal。

    

  
   
     private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
   
   
     IntentFilter filter, String broadcastPermission,
   
   
     Handler scheduler, Context context) {
   
   
     
   
   
     IIntentReceiver rd = null; //最终代替receiver传递各种语义(也就是方法的调用)
   
   
     if (receiver != null) {
   
   
     //在Android的架构里,应用进程里是用LoadedApk来对应一个apk的,进程里加载了多少个apk,就会有多少LoadedAp
   
   
     if (mPackageInfo != null && context != null) {
   
   
     if (scheduler == null) {
   
   
     //mMainThread : ActivityThread 获得它中的那个H --Handler。处理东西。 至于这个ActivityThread感觉一个进程开始运行应该就有一个。
   
   
     scheduler = mMainThread.getHandler(); 
   
   
     }
   
   
     // 查找和context对应的“子哈希表”里的ReceiverDispatcher,如果找不到,就重新new一个。
   
   
     rd = mPackageInfo.getReceiverDispatcher(
   
   
     //receiver :就是咱们写的那个实例。
   
   
     receiver, context, scheduler, //zy 这会儿的context就是指向了mainActivity的context
   
   
     mMainThread.getInstrumentation(), true);
   
   
     } else {
   
   
     if (scheduler == null) {
   
   
     scheduler = mMainThread.getHandler();
   
   
     }
   
   
     rd = new LoadedApk.ReceiverDispatcher(
   
   
     receiver, context, scheduler, null, true).getIIntentReceiver();
   
   
     }
   
   
     }
   
   
     try {
   
   
     //远程的代理直接调用AMS的registerReceiver实现。
   
   
     return ActivityManagerNative.getDefault().registerReceiver( 
   
   
     //zy mBasePackageName 应该是包名吧。
   
   
     mMainThread.getApplicationThread(), mBasePackageName, 
   
   
     rd, filter, broadcastPermission, userId); //rd 这个rd是IIntentReceiver的Binder对象传给AMS。
   
   
     } catch (RemoteException e) {
   
   
     return null;
   
   
     }
   
   
     }
   
  

    如注释中的说明,此处的关键是IIntentReceiver对象,这个对象以后就承receiver和AMS之间的通信语义的传递IntentRece iver最终的实现是在LoadedApk中。
LoadedApk这个类包含了当前加载的apk的主要的信息。
    LoadedApk此处用到它的一个非常重要的成员变量。     
private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers = new ArrayMap<Con text,ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>();里面存放的是所有
动态注册的receiver。最外层的以key = 当前动态注册的receiver运行的上下文。(有个疑问这个context是application的还是当前activity的?自己对上下文理解不深)
value = 一个集合。(因为当前运行的如Activity肯定可以注册多个receiver的,用一个集合来容纳)
在这个次级的集合中。key = 当前注册的receiver。
value = 对应的ReceiverDispatcher对象。这个类用来管理我们的
IIntentReceiver对象。
    总的来说说:
    
    
每个context对应一个receiver和
ReceiverDispatcher的集合。
     
   每个receiver对应一个ReceiverDispatcher,用来管理
IIntentReceiver

        每个
ReceiverDispatcher对应一个
IIntentReceiver。
    
    
综上也就是说,每个
receiver对应一个
IIntentReceiver。
        为什么说每个
ReceiverDispatcher对应一个
IIntentReceiver那?看
ReceiverDispatcher的构造。

   
    
      ReceiverDispatcher(BroadcastReceiver receiver, Context context, //ReceiverDispatcher的唯一构造。
    
    
      Handler activityThread, Instrumentation instrumentation,
    
    
      boolean registered) {
    
    
      if (activityThread == null) {
    
    
      throw new NullPointerException("Handler must not be null");
    
    
      }
    
    
      
    
    
      //zy mIIntentReceiver 此处很关键,可以看出来实例化一个ReceiverDispatcher就会在这个rd中实例化一个InnerReceiver
    
    
      mIIntentReceiver = new InnerReceiver(this, !registered);
    
    
      mReceiver = receiver;//zy 就是自己新建的那个receiver。
    
    
      mContext = context; //zy 此处赋值的contex是运行时的那个上下文。
    
    
      mActivityThread = activityThread;// zy 前面传过来的那个ActivityThread中的H--Handler。
    
    
      mInstrumentation = instrumentation;
    
    
      mRegistered = registered;
    
    
      mLocation = new IntentReceiverLeaked(null);
    
    
      mLocation.fillInStackTrace();
    
    
      }
    
   

    
    ReceiverDispatcher会在构造中新建一个唯一的
IIntentReceiver的对象。

     回到前面的registerReceiverInternal方法,获得到
IIntentReceiver对象rd以后。通过binder机制经行通信,传入
rd。
     最终会调到AMS中的对应的registerReceiver方法。      

  
   
     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   
   
     IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
   
   
     int callingUid;
   
   
     int callingPid;
   
   
     synchronized(this) {
   
   
     ...... //前面是一些callinguid和pid的判断
   
   
     List allSticky = null;
   
   
     
   
   
     // Look for any matching sticky broadcasts...
   
   
     Iterator actions = filter.actionsIterator();
   
   
     if (actions != null) {
   
   
     while (actions.hasNext()) {
   
   
     String action = (String)actions.next();
   
   
     allSticky = getStickiesLocked(action, filter, allSticky,
   
   
     UserHandle.USER_ALL);
   
   
     allSticky = getStickiesLocked(action, filter, allSticky,
   
   
     UserHandle.getUserId(callingUid));
   
   
     }
   
   
     } else {
   
   
     allSticky = getStickiesLocked(null, filter, allSticky,
   
   
     UserHandle.USER_ALL);
   
   
     allSticky = getStickiesLocked(null, filter, allSticky,
   
   
     UserHandle.getUserId(callingUid));
   
   
     }
   
   
     
   
   
     Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; //zy 不发送粘性广播那么这里就是null啦。
   
   
     if (receiver == null) {
   
   
     return sticky;
   
   
     }
   
   
     //zy 此处也很关键动态注册的到这以后第一次rl肯定是null。注意:receiver.asBinder()就是传过来的IIntentReceiver对象。
   
   
     ReceiverList rl
   
   
     = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   
   
     if (rl == null) {//zy 再注册一个IntentFilter时候已经不是null了就。!!
   
   
     //此处只是新建了一个ReceiverList的集合,未在里面添加任何的BroadcastFilter。
   
   
     rl = new ReceiverList(this, callerApp, callingPid, callingUid, //callerApp 一开始启动的那个进程
   
   
     userId, receiver); //把IIntentReceiver保存在ReceiverList成员变量中。
   
   
     if (rl.app != null) {
   
   
     rl.app.receivers.add(rl); //ProcessRecord.receivers保存这个进程的IIntentReceiver(用来代替我们建的receiver,谁让它不能binder传递数据那)广播接收器。
   
   
     } else {
   
   
     try {
   
   
     receiver.asBinder().linkToDeath(rl, 0);
   
   
     } catch (RemoteException e) {
   
   
     return sticky;
   
   
     }
   
   
     rl.linkedToDeath = true;
   
   
     }
   
   
     mRegisteredReceivers.put(receiver.asBinder(), rl);//此时ReceiverList里面没有BroadcastFilter!
   
   
     } 
   
   
     ......
   
   
     
   
   
     // 创建BroadcastFilter,感觉就把广播接收器列表ReceiverList和filter关联起来.
   
   
     BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 
   
   
     permission, callingUid, userId);
   
   
     rl.add(bf);//每个IntenFilter对应一个BroadcastFilter,应该是如此。
   
   
     mReceiverResolver.addFilter(bf); //zy 至此广播都保存到了AMS相关的变量中。
   
   
     
   
   
     if (allSticky != null) { // Zy 用于发出粘性广播!
   
   
     ArrayList receivers = new ArrayList();
   
   
     receivers.add(bf);
   
   
     
   
   
     int N = allSticky.size();
   
   
     for (int i=0; i<N; i++) {
   
   
     Intent intent = (Intent)allSticky.get(i);
   
   
     BroadcastQueue queue = broadcastQueueForIntent(intent);
   
   
     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
   
   
     null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
   
   
     null, null, false, true, true, -1);
   
   
     queue.enqueueParallelBroadcastLocked(r);
   
   
     queue.scheduleBroadcastsLocked();
   
   
     }
   
   
     }
   
   
     
   
   
     return sticky;
   
   
     }
   
   
     }
   
  

         此处首先看一下粘性广播的部分,由于此处没有经行实际的验证,一下关于粘性广播只是个人的理解猜测。一些列的
    
 
判断后,如果发现是粘性广播那么,直接queue.scheduleBroadcastsLocked(),执行已经注册过的receiver。          然后就是关键的BroadcastFilter部分了。先介绍AMS的一个相关的成员变量。      final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 
new HashMap<IBinder, ReceiverList>();
     key = Ibinder对象,其实就是我们传过来的
IIntentReceiver对象。(由于本身对binder理解不深)此处暂把,     
 
IIntentReceiver..asBinder()。就当成
IIntentReceiver对象。此处重在理解思想。


     value = ReceiverList 对象。此处的
ReceiverList
 是一个ArrayList集合,里面存放的只能是BroadcastFilter,这个对象      有一些自己的成员变量。这样看来的话,一个
IIntentReceiver
也就是一个receiver可以有多个
BroadcastFilter。
     ReceiverList中的一个值得一提的成员变量:
         
 
public final IIntentReceiver receiver;保存传过来的这个
IIntentReceiver对象,也就对应到我们注册receiver。
     综上看来:
     其实
mRegisteredReceivers
 对应于LoadedApk中的
mReceivers 。都是和动态注册相关的。
     每个
IIntentReceiver对象对应一个
ReceiverList
对象。
     每个
ReceiverList对象可以对应多个
BroadcastFilter。          (个人理解同一个receiver可以注册多个IntentFilter嘛,每个filter对应一个BroadcastFilter。)
         那么
BroadcastFilter对象是用来干么的那?对此我理解的也不深,就把它当成了一个封装某些属性的IntentFilter对      象。里面有包名和所需权限等。值的一提的属性final ReceiverList receiverList;标记这个bf属于哪个
ReceiverList。
     最后再调用 mReceiverResolver.addFilter(bf),把
BroadcastFilter添加到AMS的成员变量mReceiverResolver中。      至此动态注册相关的知识点介绍完毕,以上都是个人的理解可能存在一些错误,欢迎指正。     
    2.2、静态注册的receiver。

    
     其实就是在安装APK的时候,对manifest中的receiver节点经行解析,放到相应的内存(成员变量)中。这个解析是有PMS
      进行的。注意:常驻内存的是静态receiver的描述信息,而不是receiver本身。

    
     一个重要的接口PMS中的queryIntentReceivers。返回一个List<ResolveInfo>,(个人理解这块查到的好像就是已经按       照propity排好序的,暂无深究)。
ResolveInfo类算是静态注册时包含广播的注册信息的类。关于PMS解析apk,在博客的


      另一个文章有个流程,不过那个流程只是详细的分析啦一下和权限相关的,也可以仿照的分析一下静态的。


3、广播的发送过程。
       广播的发送有好几种,有序的、普通的、粘性广播等。最终无非就是传入的参数不同,此处对这些基础的就不再总结。不过
   在下面的分析中会,依次把各
个参数区别,在注释中写清楚

   下面是自己在调试的时候写的一个例子。

  
   
            Intent in = new Intent("com.zy.test");
   
   
     //ComponentName cn = new ComponentName("com.zy.receiver_test","com.zy.receiver_test.receiverfour");
   
   
     //in.setComponent(cn);
   
   
     android.util.Log.d("zy_rec","send_order");
   
   
     MainActivity.this.sendBroadcast(in);
   
  

    当前进程最终会调用到ContextImpl中的sendBroadcast接口。

   
    
      @Override
    
    
      public void sendBroadcast(Intent intent) {
    
    
      warnIfCallingFromSystemProcess();
    
    
      String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    
    
      try {
    
    
      intent.prepareToLeaveProcess();
    
    
      ActivityManagerNative.getDefault().broadcastIntent(
    
    
      mMainThread.getApplicationThread(), intent, resolvedType, null, //IIntentReceiver 是null。
    
    
      Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, false,
    
    
      getUserId());
    
    
      } catch (RemoteException e) {
    
    
      }
    
    
      }
    
   

     需要注意一下,此处传入的两个false,代表无序、非粘性。并且
IIntentReceiver传入的是null。然后通过binder调用到了AMS
broadcastIntent,然后最终调用到AMS的broadcastIntentLocked。
 
 主要的代码和分析如下:

  
   
     private final int broadcastIntentLocked(ProcessRecord callerApp, //zy
   
   
     String callerPackage, Intent intent, String resolvedType,
   
   
     IIntentReceiver resultTo, int resultCode, String resultData, // zy 发送的时候resultTo好像都是null。
   
   
     Bundle map, String requiredPermission, int appOp,
   
   
     boolean ordered, boolean sticky, int callingPid, int callingUid, //zy ordered 是否是有序的 ,sticky是否是发送的粘性广播
   
   
     int userId) {
   
   
     intent = new Intent(intent);
   
   
     
   
   
     // By default broadcasts do not go to stopped apps.
   
   
     //如果一个应用在安装后从来没有启动过,或者已经被用户强制停止了,那么这个应用就处于停止状态:stopped state
   
   
     //zy FLAG_INCLUDE_STOPPED_PACKAGES、FLAG_EXCLUDE_STOPPED_PACKAGES
   
   
     //在默认情况下,AMS是不会把intent广播发给“处于停止状态的”应用的。
   
   
     intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); //zy 
   
   
     ...... //一些合法性的判断和protected-broadcast权限判断
   
   
     
   
   
     final String action = intent.getAction();
   
   
     if (action != null) { // zy 各种系统广播的处理。 
   
   
     ......
   
   
     }
   
   
     
   
   
     // Add to the sticky list if requested. 
   
   
     if (sticky) { // zy 如果是发送的粘性广播,必须把intent记录下来。
   
   
     if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, // 先检查权限。
   
   
     callingPid, callingUid)
   
   
     != PackageManager.PERMISSION_GRANTED) {
   
   
     ......
   
   
     }
   
   
     if (requiredPermission != null) {
   
   
     ......
   
   
     return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; //粘性广播不可以有权限。
   
   
     }
   
   
     if (intent.getComponent() != null) {
   
   
     throw new SecurityException(
   
   
     "Sticky broadcasts can't target a specific component");//粘性广播不可以指定specific component。
   
   
     }
   
   
     if (userId != UserHandle.USER_ALL) {
   
   
     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
   
   
     UserHandle.USER_ALL);
   
   
     if (stickies != null) {
   
   
     ArrayList<Intent> list = stickies.get(intent.getAction());
   
   
     if (list != null) {
   
   
     int N = list.size();
   
   
     int i;
   
   
     for (i=0; i<N; i++) {
   
   
     if (intent.filterEquals(list.get(i))) { //不要和全局的已经存在的粘性广播冲突。
   
   
     throw new IllegalArgumentException(
   
   
     "Sticky broadcast " + intent + " for user "
   
   
     + userId + " conflicts with existing global broadcast");
   
   
     }
   
   
     }
   
   
     }
   
   
     }
   
   
     }
   
   
     
   
   
     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   
   
     if (stickies == null) {
   
   
     stickies = new ArrayMap<String, ArrayList<Intent>>();
   
   
     mStickyBroadcasts.put(userId, stickies);
   
   
     }
   
   
     ArrayList<Intent> list = stickies.get(intent.getAction());
   
   
     if (list == null) {
   
   
     list = new ArrayList<Intent>();
   
   
     stickies.put(intent.getAction(), list);
   
   
     }
   
   
     int N = list.size();
   
   
     int i;
   
   
     for (i=0; i<N; i++) {//遍历所有的这个action对应的inetnt。
   
   
     if (intent.filterEquals(list.get(i))) {
   
   
     // This sticky already exists, replace it.
   
   
     list.set(i, new Intent(intent)); //如果已经存在覆盖一下。
   
   
     break;
   
   
     }
   
   
     }
   
   
     if (i >= N) {//一直没存在是上面的for不会break,那么就会大于等于。
   
   
     //添加进去。到此为止粘性广播就添加到列表中了。然后在注册的时候读取列表看看是不是已经注册,决定是否直接执行广播发送。
   
   
     list.add(new Intent(intent));
   
   
     }
   
   
     }
   
   
     
   
   
     // Figure out who all will receive this broadcast.
   
   
     List receivers = null;
   
   
     List<BroadcastFilter> registeredReceivers = null;
   
   
     // Need to resolve the intent to interested receivers...
   
   
     if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)== 0) {
   
   
     receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); // 收集都是参数中intent相关的通过静态注册或者指定Component的广播。
   
   
     }
   
   
     if (intent.getComponent() == null) {
   
   
     if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
   
   
     ...... // 系统的uid的一些处理
   
   
     } else {
   
   
     // zy 前面分析动态注册的时候最终把BroadcastFilter保存在了成员变量mReceiverResolver中。此处取出来和参数中intent相关的广播。
   
   
     registeredReceivers = mReceiverResolver.queryIntent(intent,resolvedType, false, userId);
   
   
     }
   
   
     }
   
   
     
   
   
     final boolean replacePending =
   
   
     (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; //这个好像是用来标记是否以前发送过这个广播。
   
   
     int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 
   
   
     if (!ordered && NR > 0) { // r如果不是有序广播,并且有动态注册的receiver。那么下面就开始直接进行处理。
   
   
     final BroadcastQueue queue = broadcastQueueForIntent(intent);
   
   
     // BroadcastQueue封装一个类,记录了这个广播是由谁发出的以及要发给谁等相关信息.
   
   
     //发送一次广播至少有一个BroadcastRecord,也有可能是两个,需要看是发送的什么类型的广播,以及都有那些receiver,通过什么方式注册的。
   
   
     BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 
   
   
     callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
   
   
     //由前面的注册信息可知,此时的registeredReceivers只包含了BroadcastFilter。
   
   
     appOp, registeredReceivers, resultTo, resultCode, resultData, map,
   
   
     ordered, sticky, false, userId);
   
   
     final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
   
   
     if (!replaced) {
   
   
     //zy 就会把这个广播记录块r放在BroadcastQueue中的mParcelBroadcasts,只会对应动态receiver.也就是说mParcelBroadcasts里面只有BroadcastFilter.
   
   
     queue.enqueueParallelBroadcastLocked(r); 
   
   
     queue.scheduleBroadcastsLocked(); //通过handler去异步执行的,发送到Handler就不管了。
   
   
     }
   
   
     registeredReceivers = null // 发送无序广播的时候处理完动态注册的就直接把registeredReceivers置为null了,方便对不是无序广播的处理。
   
   
     NR = 0; //通过它控制,下面receiver的列表也不需要整合,直接处理静态的。
   
   
     }
   
   
     
   
   
     // Merge into one list. //此处把动态的和静态的合入到一个列表
   
   
     int ir = 0;
   
   
     if (receivers != null) { //需要把动态的合入到静态的里面。 receivers 某个intent对应的所有的静态的。
   
   
     ......// 防止一些应用正在安装的时候可以监听 PACKAGE_ADDED,然后利用这个启动起来。
   
   
     
   
   
     //zy 然后开始整合列表。
   
   
     int NT = receivers != null ? receivers.size() : 0;
   
   
     int it = 0;
   
   
     ResolveInfo curt = null;
   
   
     BroadcastFilter curr = null;
   
   
     while (it < NT && ir < NR) {//当NR > 0,也就是不是无序的广播的时候,因为无序广播时有在前面进行处理。
   
   
     if (curt == null) {
   
   
     curt = (ResolveInfo)receivers.get(it);
   
   
     }
   
   
     if (curr == null) {
   
   
     curr = registeredReceivers.get(ir); //发送有序广播时,此时registeredReceivers不等于null。
   
   
     }
   
   
     if (curr.getPriority() >= curt.priority) {
   
   
     // Insert this broadcast record into the final list. //一个个对比 ,如果发现 动态注册的 priority大于静态的,插进去。
   
   
     receivers.add(it, curr);
   
   
     ir++;
   
   
     curr = null;
   
   
     it++;
   
   
     NT++;
   
   
     } else {
   
   
     // Skip to the next ResolveInfo in the final list.
   
   
     it++;
   
   
     curt = null;
   
   
     }
   
   
     }
   
   
     }
   
   
     while (ir < NR) {
   
   
     if (receivers == null) {
   
   
     receivers = new ArrayList();
   
   
     }
   
   
     receivers.add(registeredReceivers.get(ir)); //动态注册的比较长时候,接着往后面加入。至此算是合并完毕。
   
   
     ir++;
   
   
     }
   
   
     
   
   
     //下面开始处理合并好的广播列表。
   
   
     if ((receivers != null && receivers.size() > 0)
   
   
     || resultTo != null) { // resultTo 正常发送的时候传入的是null,但此时是或啊,前面符合也行。
   
   
     BroadcastQueue queue = broadcastQueueForIntent(intent);
   
   
     BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   
   
     callerPackage, callingPid, callingUid, resolvedType,
   
   
     //下面的receivers 此时这个BroadcastRecord中的receivers就可能是BroadcastFilter或者ResolveInfo
   
   
     requiredPermission, appOp, receivers, resultTo, resultCode, 
   
   
     resultData, map, ordered, sticky, false, userId);
   
   
     boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 
   
   
     if (!replaced) {
   
   
     // 注意此处,就算是r 的receiver=5;也是只有一个BroadcastRecord!
   
   
     // 那么问题来了,如何有好几个那?个人理解是,通过发送多次广播达到有好几次广播记录。
   
   
     queue.enqueueOrderedBroadcastLocked(r); //zy 放入到Broadcastqueen的mOrderedBroadcasts当中。
   
   
     queue.scheduleBroadcastsLocked();// 交给Handler串行处理。
   
   
     }
   
   
     }
   
   
     return ActivityManager.BROADCAST_SUCCESS;
   
   
     }
   
  

    说以下主要内容:
    
    
1、
先是设置一个flag,防止一些流氓应用通过监听系统广播自启动。      
   2、处理一些系统的广播如Intent.ACTION_UID_REMOVED
Intent.ACTION_PACKAGE_CHANGED、Intent.ACTION_PACKAGE_ADDE            Intent.ACTION_TIME_CHANGED、Intent.ACTION_TIMEZONE_CHANGED等等。     
    3、如果发送的是粘性广播对其进行相关处理。

        4、分别获取对传过来的intent感兴趣的动态注册的receiver集合和静态注册的receiver集合。     
    
    
List receivers = null;一开始获取的存放的是静态注册的receiver,有可能后面会合入动态的。         
    
List<BroadcastFilter> registeredReceivers = null;获取的是动态注册的receiver。             通过Log验证此时:     
    
    
   a、
 
receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
                 没有分析
collectReceiverComponents里面的更具体的实现。
                一种是获取的静态注册的,此时获取出来的都是已经按照propity排序好的!(个人感觉propity相同时,应该是按
                照先解析的谁,谁在前面。apk在不同的目录下肯定有不同的解析顺序)
                一种是获取的是指定
Component的receiver。此时:就算是别的通过静态注册了,也不会查询出来,只会有你指定                 的
omponent的那个,而且(写了两个测试程序,竟然有一个死活查询不出来,抽时间真的分析内部实现)
               b、 
registeredReceivers = mReceiverResolver.queryIntent(intent,
resolvedType, false, userId);
                  也没有分析
queryIntent内部的详细实现。
                  通过程序测试,发现动态的查询出来也是按照propity排好序的,如果是相同的propity,那么谁先注册先理。          5、接下来通过是否是有序广播,如果是无序的并且有动态注册的receiver对此Intent感兴趣,先创建一个BroadcastRecord一次性处理这些平行
广播。
         6、判断是否要合并广播列表。如果需要则按照propity进行合并。并放到
receivers
 当中。
         7、依次处理
receivers
 中的广播了,有可能是动态注册的有可能是静态注册的,也是:BroadcastFilter
ResolveInfo       综上:           有个类就很关键了,那就是BroadcastRecord.它封装了
这一次的send广播的一些信息,有可能被创建个
BroadcastRecord
      重要的成员变量有:     
    
   final Intent intent;  用来创建这个
BroadcastRecord的intent

           final List receivers; 要接收这个广播的receiver的集合,可以是
BroadcastFilter、或者
ResolveInfo,也可以都有。     
    
   int nextReceiver; // 下一个要处理的receiver,用于静态注册的在BroadcastQueen里面使用。

   
    
     BroadcastRecord(BroadcastQueue _queue,
    
    
      Intent _intent, ProcessRecord _callerApp, String _callerPackage,
    
    
      int _callingPid, int _callingUid, String _resolvedType, String _requiredPermission,
    
    
      int _appOp, List _receivers, IIntentReceiver _resultTo, int _resultCode,
    
    
      String _resultData, Bundle _resultExtras, boolean _serialized,
    
    
      boolean _sticky, boolean _initialSticky,
    
    
      int _userId) {
    
    
      queue = _queue;
    
    
      intent = _intent;
    
    
      targetComp = _intent.getComponent();
    
    
      callerApp = _callerApp;
    
    
      callerPackage = _callerPackage;
    
    
      callingPid = _callingPid;
    
    
      callingUid = _callingUid;
    
    
      resolvedType = _resolvedType;
    
    
      requiredPermission = _requiredPermission;
    
    
      appOp = _appOp;
    
    
      receivers = _receivers;
    
    
      resultTo = _resultTo;
    
    
      resultCode = _resultCode;
    
    
      resultData = _resultData;
    
    
      resultExtras = _resultExtras;
    
    
      ordered = _serialized;
    
    
      sticky = _sticky;
    
    
      initialSticky = _initialSticky;
    
    
      userId = _userId;
    
    
      nextReceiver = 0; // zy nextReceiver默认是0
    
    
      state = IDLE;
    
    
      }
    
   

     也就是说每一次的广播发送,对应一个或者两个BroadcastRecord。需要看注册这个action的广播是怎么实现的啊。    a、如果只有动态
注册的或者只有静态注册的(无论是有序还是无序),都只实例化一个
BroadcastRecord,
   b、如果既有动态注册的receiver又有静态注册的receiver都对这个intent感兴趣,那么害的分情况     
    当是无序广播时:会有两个
BroadcastRecord。


        当是有序广播时:还是只实例化一个
BroadcastRecord。
   综上可见:     
    a、广播注册的时候不会排序,而在发送的时候实时的去获取并排序receiver。


        b、receiver的接受处理顺序。     
    
   当发送的是有序广播:按照receiver的propity进行顺序接收,无论是什么注册方式,默认优先级的0。
                               数字越大,优先级越高。现在没有-1000~1000的限制了,int范围内就行,自
                               己设置的19999也可以。源码那块并没有进行判断。当时相同propity的时候谁

                               先注册,谁先收到。            当发送的是无序广播:动态注册的肯定比静态注册的先执行。当都是动态注册的时候,propity高的先执行                                而当propity又一样时,先注册的先执行。当都是静态注册的时候,也是propity高的                                先执行,(一样的时候感觉是按照解析顺序,谁先解析谁先执行)



4、广播的处理过程。
    前面的发送过程我们分析到如下两个地方:     a、处理平行广播

   
    
 
queue.enqueueParallelBroadcastLocked(r);          queue.scheduleBroadcastsLocked();     b、处理有序广播        
queue.enqueueOrderedBroadcastLocked(r);         queue.scheduleBroadcastsLocked();     下面我们一个个的分析。     BroadcastQueue的enqueueParallelBroadcastLocked和
enqueueOrderedBroadcastLocked
方法。    

  
   
     public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
   
   
     mParallelBroadcasts.add(r);
   
   
     }
   
  

    

  
   
     public void enqueueOrderedBroadcastLocked(BroadcastRecord r) {
   
   
     mOrderedBroadcasts.add(r);
   
   
     }
   
  

    很简单就是分别往成员变量mParallelBroadcasts和mOrderedBroadcasts中添加元素。

    final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<BroadcastRecord>();里面的
BroadcastRecord的成员变量
    receivers
所携带的只能有BroadcastFilter。
    final ArrayList<BroadcastRecord> mOrderedBroadcasts = new ArrayList<BroadcastRecord>();
里面的
BroadcastRecord的成员变量

    receivers可以携带
BroadcastFilter和ResolveInfo。也可以只有
ResolveInfo或者
BroadcastFilter。

    
此处个人的理解:之所以把mParallelBroadcasts称为平行广播,是因为要在一次processNextBroadcas中对集合里面的所有receiver全部处理完,但是平行广播,内部也是必然有一定的顺序的。mOrderedBroadcasts称为串行广播,因为在处理的时候一次
processNextBroadcas
只能执行
mOrderedBroadcasts集合里面的一个元素。
    
此处还有一个值得一提的点:在执行a或者b的处理过程前,会调用。BroadcastQueue queue = broadcastQueueForIntent(inte nt);来获得合适的BroadcastQueue。在AMS中有两个:(主要是它们的响应超时的时间长短不同)
    
    
BroadcastQueue mFgBroadcastQueue;    
    
 BroadcastQueue mBgBroadcastQueue;     
    
final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
    他们在构造中分别经行初始化。         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
“foreground”, BROADCAST_FG_TIMEOUT, false);         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
 “background”, BROADCAST_BG_TIMEOUT, true);         mBroadcastQueues[0] = mFgBroadcastQueue;         mBroadcastQueues[1] = mBgBroadcastQueue;     对应的name和timeoutPeriod不一样,那么就没什么说的,不过这个
timeoutPeriod代表了响应超时的时间。
         
    
static final int BROADCAST_BG_TIMEOUT = 60*1000;//后台
Boradcastqueue
 60S的时间。
        这个响应时间,60S或者10S是针对一个receiver说的。比如说某个前台广播的某个BroadcastRecord携带了5个receiver,那么这一次的广播
记录只要在5*60S内完成即可。事实上AMS考虑啦更多的东西,所以总时限是所有的receiver时限之和的两倍2*5*60S。通过代码观察其实,这个时
限对应的receiver只限于通过queue.enqueueOrderedBroadcastLocked(r)加入到串行广播列表中的receiver。并没有考虑加入到并行广播列表的     
receiver的个数。


    接下来分析
queue.scheduleBroadcastsLocked()方法。分析之前先看一下BroadcastQueue的构造。     

  
   
     BroadcastQueue(ActivityManagerService service, Handler handler,
   
   
     String name, long timeoutPeriod, boolean allowDelayBehindServices) {
   
   
     mService = service;
   
   
     mHandler = new BroadcastHandler(handler.getLooper());
   
   
     mQueueName = name;
   
   
     mTimeoutPeriod = timeoutPeriod;
   
   
     mDelayBehindServices = allowDelayBehindServices;
   
   
     }
   
  

    以及BroadcastHandler的实现。

   
    
      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, "Received BROADCAST_INTENT_MSG");
    
    
      processNextBroadcast(true); // 处理广播
    
    
      } break;
    
    
      case BROADCAST_TIMEOUT_MSG: { //用来处理超时的事件。
    
    
      synchronized (mService) {
    
    
      broadcastTimeoutLocked(true);
    
    
      }
    
    
      } break;
    
    
      }
    
    
      }
    
    
      };
    
   

     那么BroadcastQueue的方法scheduleBroadcastsLocked最终会调用到processNextBroadcast如下,通过发送BROADCAST_INTENT_MSG。

   
    
      public void scheduleBroadcastsLocked() {
    
    
      if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts ["
    
    
      + mQueueName + "]: current="
    
    
      + mBroadcastsScheduled);
    
    
      
    
    
      if (mBroadcastsScheduled) {
    
    
      return;
    
    
      }
    
    
      mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
    
    
      mBroadcastsScheduled = true;
    
    
      }
    
   

     接下里就是非常重要的processNextBroadcast()的方法介绍了,还是同样先贴出主要的代码以及注释的分析。

   
    
      final void processNextBroadcast(boolean fromMsg) {
    
    
      synchronized(mService) {
    
    
      BroadcastRecord r;
    
    
      
    
    
      if (fromMsg) {
    
    
      mBroadcastsScheduled = false;//设置成false ,让下一个广播可以进入mHandler消息队列当中。
    
    
      }
    
    
      //zy 首先处理所有的平行广播mParallelBroadcasts。
    
    
      while (mParallelBroadcasts.size() > 0) {
    
    
      r = mParallelBroadcasts.remove(0);
    
    
      r.dispatchTime = SystemClock.uptimeMillis();
    
    
      r.dispatchClockTime = System.currentTimeMillis();
    
    
      final int N = r.receivers.size();//通过前面的分析可知,此时的r.receivers里面的都是BroadcastFilter,也就是动态注册的。
    
    
      for (int i=0; i<N; i++) {
    
    
      Object target = r.receivers.get(i);
    
    
      deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);// 此处去真正的处理,后面再分析。
    
    
      }
    
    
      addBroadcastToHistoryLocked(r);
    
    
      }
    
    
      //mPendingBroadcast成员变量表示我们即将处理的BroadcastRecord,(等待进程的启动)默认是null。
    
    
      if (mPendingBroadcast != null) { //首次到这肯定是null的。
    
    
      boolean isDead;
    
    
      synchronized (mService.mPidsSelfLocked) {
    
    
      ProcessRecord proc = mService.mPidsSelfLocked.get(mPendingBroadcast.curApp.pid);
    
    
      isDead = proc == null || proc.crashing;
    
    
      }
    
    
      if (!isDead) {
    
    
      // It's still alive, so keep waiting
    
    
      return;
    
    
      } else {
    
    
      Slog.w(TAG, "pending app ["
    
    
      + mQueueName + "]" + mPendingBroadcast.curApp
    
    
      + " died before responding to broadcast");
    
    
      mPendingBroadcast.state = BroadcastRecord.IDLE;
    
    
      mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
    
    
      mPendingBroadcast = null;
    
    
      }
    
    
      }
    
    
      boolean looped = false;
    
    
      do {
    
    
      // 注意此处很关键,用来退出这个处理。
    
    
      // 在下面的一个判断中mOrderedBroadcasts.remove(0) 这边就有可能变成mOrderedBroadcasts.size() == 0。
    
    
      if (mOrderedBroadcasts.size() == 0) {
    
    
      mService.scheduleAppGcsLocked();
    
    
      if (looped) {
    
    
      mService.updateOomAdjLocked();
    
    
      }
    
    
      return;
    
    
      }
    
    
      r = mOrderedBroadcasts.get(0);//取出mOrderedBroadcasts中最顶部的那个BroadcastRecord,进行处理。
    
    
      boolean forceReceive = false;
    
    
      //标记的是mOrderedBroadcasts中的receiver的个数。
    
    
      int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
    
    
      if (mService.mProcessesReady && r.dispatchTime > 0) {
    
    
      long now = SystemClock.uptimeMillis();
    
    
      //由下面这个判断就可知总的时间是:(两倍的(mTimeoutPeriod*mOrderedBroadcasts中的receiver的个数))
    
    
      if ((numReceivers > 0) &&(now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
    
    
      broadcastTimeoutLocked(false); // 强行终止这个广播。
    
    
      forceReceive = true;
    
    
      r.state = BroadcastRecord.IDLE;//恢复初始状态。
    
    
      }
    
    
      }
    
    
      
    
    
      if (r.state != BroadcastRecord.IDLE) {
    
    
      ......
    
    
      return;
    
    
      }
    
    
      //此处的判断也是很关键的,默认第一次r.nextReceiver = 0,但是它每次都会++,等待最后一个处理完了,
    
    
      //它还会再++试图去处理一个不存在的nextReceiver,此时r.nextReceiver >= numReceivers就成立了,就
    
    
      //会进入到这个判断。当然还有别的条件可以进入如:前面的超时时候forceReceive = true。
    
    
      if (r.receivers == null || r.nextReceiver >= numReceivers 
    
    
      || r.resultAbort || forceReceive) { 
    
    
      // 还有没有处理的时候r.resultTo != null,通过r.nextReceiver >= numReceivers进来的一般都是null
    
    
      if (r.resultTo != null) {
    
    
      try {
    
    
      
    
    
      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) {
    
    
      }
    
    
      }
    
    
      cancelBroadcastTimeoutLocked();//取消超时设置。
    
    
      
    
    
      // ... and on to the next...
    
    
      addBroadcastToHistoryLocked(r);
    
    
      //由于本次正在处理的BroadcastRecord中所有的receiver已经处理完,
    
    
      //移除掉最上面的BroadcastRecord,假如它里面还有就进行下一个处理。
    
    
      mOrderedBroadcasts.remove(0);
    
    
      r = null;//然后置为null,那么此时算是一个BroadcastRecord处理完毕,
    
    
      looped = true;
    
    
      continue; // 进入下一个循环。
    
    
      }
    
    
      } while (r == null);
    
    
      
    
    
      //注意此处是先赋值再++。也就是说 recIdx = 当前的receiver的索引。然后到下面的语句的时候r.nextReceiver = recIdx+1啦.
    
    
      //比如第一次r.nextReceiver = 0, 执行完后 recIdx = 0,r.nextReceiver = 1.
    
    
      int recIdx = r.nextReceiver++;
    
    
      
    
    
      r.receiverTime = SystemClock.uptimeMillis();
    
    
      if (recIdx == 0) {
    
    
      r.dispatchTime = r.receiverTime;// diyici 记录一下开始的时间,按照第一个receiver开始处理的时间
    
    
      r.dispatchClockTime = System.currentTimeMillis();
    
    
      }
    
    
      if (!mPendingBroadcastTimeoutMessage) {
    
    
      long timeoutTime = r.receiverTime + mTimeoutPeriod;
    
    
      //如果没有设置超时事件,那么就进行设置,从此处也可一看出来是每个timeoutTime对应于一个receiver。
    
    
      setBroadcastTimeoutLocked(timeoutTime);
    
    
      }
    
    
      Object nextReceiver = r.receivers.get(recIdx); //注意!!!它取出来的其实是BoradcastRecord的receivers中的当前正在处理的receiver。
    
    
      if (nextReceiver instanceof BroadcastFilter) {//看看是不是动态注册的,是的话直接处理。
    
    
      BroadcastFilter filter = (BroadcastFilter)nextReceiver;
    
    
      deliverToRegisteredReceiverLocked(r, filter, r.ordered);
    
    
      if (r.receiver == null || !r.ordered) {
    
    
      r.state = BroadcastRecord.IDLE;// 初始化
    
    
      scheduleBroadcastsLocked();// 执行下一个
    
    
      }
    
    
      return; //处理完直接返回,保证在mOrderedBroadcasts是串行处理的。
    
    
      }
    
    
      
    
    
      ResolveInfo info = (ResolveInfo)nextReceiver;//假如没有返回,那么必定是静态注册的,对应于ResolveInfo
    
    
      //取出注册对应的ComponentName。注意info.activityInfo.applicationInfo.packageName是包名,info.activityInfo.name类名。
    
    
      //如:com.android.zy com.android.zy.TestReceiver.(全路径)
    
    
      ComponentName component = new ComponentName(
    
    
      info.activityInfo.applicationInfo.packageName,
    
    
      info.activityInfo.name);
    
    
      
    
    
      boolean skip = false;
    
    
      ......// 一系列的权限和进程是否合法等的判断,如果不符合提要求skip = true
    
    
      
    
    
      if (skip) {
    
    
      r.receiver = null;
    
    
      r.curFilter = null;
    
    
      r.state = BroadcastRecord.IDLE;
    
    
      scheduleBroadcastsLocked(); //如果跳过的话,直接进行下一次的广播处理。
    
    
      return;
    
    
      }
    
    
      
    
    
      r.state = BroadcastRecord.APP_RECEIVE;
    
    
      String targetProcess = info.activityInfo.processName;
    
    
      r.curComponent = component;//注意此处包含我们静注册的receiver的信息。
    
    
      final int receiverUid = info.activityInfo.applicationInfo.uid;
    
    
      if (r.callingUid != Process.SYSTEM_UID && isSingleton
    
    
      && mService.isValidSingletonCall(r.callingUid, receiverUid)) {
    
    
      info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
    
    
      }
    
    
      r.curReceiver = info.activityInfo;
    
    
      try {
    
    
      //开始处理这个广播,那么这个包不能被停止。
    
    
      AppGlobals.getPackageManager().setPackageStoppedState(
    
    
      r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid));
    
    
      } catch (RemoteException e) {
    
    
      } catch (IllegalArgumentException e) {
    
    
      }
    
    
      //获得当前需要处理的进程记录。由于是静态注册的那么receiver所在的进程有可能是正在运行的,也有可能格式未启动的。
    
    
      ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
    
    
      info.activityInfo.applicationInfo.uid, false);
    
    
      //如果当前进程已经存在那么直接调用processCurBroadcastLocked()做进一步的处理。
    
    
      if (app != null && app.thread != null) {
    
    
      try {
    
    
      app.addPackage(info.activityInfo.packageName,
    
    
      info.activityInfo.applicationInfo.versionCode, mService.mProcessStats);
    
    
      android.util.Log.d("zy_rec", "app != null && app.thread != null info.activityInfo.name = "+info.activityInfo.name); 
    
    
      processCurBroadcastLocked(r, app);
    
    
      return;
    
    
      } catch (RemoteException e) {
    
    
      } catch (RuntimeException e) {
    
    
      logBroadcastReceiverDiscardLocked(r);
    
    
      finishReceiverLocked(r, r.resultCode, r.resultData,
    
    
      r.resultExtras, r.resultAbort, false);
    
    
      scheduleBroadcastsLocked();
    
    
      r.state = BroadcastRecord.IDLE;
    
    
      return;
    
    
      }
    
    
      }
    
    
      // zy 如果不存在,那么我们需要先启动这个进程,通过startProcessLocked()方法。
    
    
      //启动成功后会调用AMS的attachApplication()。
    
    
      if ((SystemProperties.getInt("sys.quickboot.enable", 0) == 1 &&
    
    
      SystemProperties.getInt("sys.quickboot.poweron", 0) == 0 &&
    
    
      !getWhiteList().contains(info.activityInfo.applicationInfo.packageName))
    
    
      || (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) {
    
    
      //启动失败会进入到此方法体内。
    
    
      logBroadcastReceiverDiscardLocked(r);
    
    
      finishReceiverLocked(r, r.resultCode, r.resultData,
    
    
      r.resultExtras, r.resultAbort, false);
    
    
      scheduleBroadcastsLocked();
    
    
      r.state = BroadcastRecord.IDLE;
    
    
      return;
    
    
      }
    
    
      
    
    
      mPendingBroadcast = r; //然后把当前的BroadcastRecord设置为即将启动的BroadcastRecord。
    
    
      mPendingBroadcastRecvIndex = recIdx;//设置当前的receiver的索引,用来表示将要启动的。
    
    
      }
    
    
      }
    
   

      个人感觉以上的代码已经十分的精简了,注释也说明的较为详细。通过上面的分析我们发现通过动态注册的也就是receiver是BroadcastFilter最后是通过deliverToRegisteredReceiverLocked去处理的,通过静态注册的也就是receiver是ResolveInfo的最终通processCurBroadcastLocked     那么通过静态注册,但是进程没有启动的那?接下来去分析一下AMS中的

    进程启动成功后会调用attachApplication,然后调用到attachApplicationLocked。而在
attachApplicationLocked方法中有调用一个

    

  
   
     private final boolean attachApplicationLocked(IApplicationThread thread,
   
   
     int pid) {
   
   
     ......
   
   
     // Check if a next-broadcast receiver is in this process...
   
   
     if (!badApp && isPendingBroadcastProcessLocked(pid)) { //进程成功启动后。
   
   
     try {
   
   
     didSomething |= sendPendingBroadcastsLocked(app); //新启动的是刚才receiver的
   
   
     } catch (Exception e) {
   
   
     // If the app died trying to launch the receiver we declare it 'bad'
   
   
     Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
   
   
     badApp = true;
   
   
     }
   
   
     }
   
   
     ......
   
   
     }
   
  

    然后是调用sendPendingBroadcastsLocked

   
    
      // The app just attached; send any pending broadcasts that it should receive
    
    
      boolean sendPendingBroadcastsLocked(ProcessRecord app) {
    
    
      boolean didSomething = false;
    
    
      for (BroadcastQueue queue : mBroadcastQueues) { // zy
    
    
      didSomething |= queue.sendPendingBroadcastsLocked(app);
    
    
      }
    
    
      return didSomething;
    
    
      }
    
   

     又调回到BroadcastQueue中的sendPendingBroadcastsLocked方法内。     

  
   
     public boolean sendPendingBroadcastsLocked(ProcessRecord app) {
   
   
     boolean didSomething = false;
   
   
     final BroadcastRecord br = mPendingBroadcast;
   
   
     if (br != null && br.curApp.pid == app.pid) {
   
   
     try {
   
   
     mPendingBroadcast = null;
   
   
     processCurBroadcastLocked(br, app);
   
   
     didSomething = true;
   
   
     } catch (Exception e) {
   
   
     logBroadcastReceiverDiscardLocked(br);
   
   
     finishReceiverLocked(br, br.resultCode, br.resultData,
   
   
     br.resultExtras, br.resultAbort, false);
   
   
     scheduleBroadcastsLocked();
   
   
     // We need to reset the state if we failed to start the receiver.
   
   
     br.state = BroadcastRecord.IDLE;
   
   
     throw new RuntimeException(e.getMessage());
   
   
     }
   
   
     }
   
   
     return didSomething;
   
   
     }
   
  

     现在明了了,进程启动完毕后最终会调用到processCurBroadcastLocked对静态注册的receiver经行进一步的处理。      那么接下来就是分析
deliverToRegisteredReceiverLocked和
processCurBroadcastLocked了。

 
    先分析
deliverToRegisteredReceiverLocked方法。     

  
   
     private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
   
   
     BroadcastFilter filter, boolean ordered) {
   
   
     boolean skip = false;
   
   
     ......//还是进行以系列的权限相关的判断。不符合要求skip = true。
   
   
     
   
   
     if (!skip) {
   
   
     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.curReceiver = r;
   
   
     mService.updateOomAdjLocked(r.curApp);
   
   
     }
   
   
     }
   
   
     try {
   
   
     //无论是不是有序最终都调用performReceiveLocked做进一步的处理
   
   
     //注意很关键的一个参数
    filter
    .
    receiverList
    .
    receiver,
    对应于这个BroadcastFilter所属的ReceiverList中对应的IInterReceiver对象。
   
   
     //就是对应于前面动态注册时,从用户进程传过来的
    IInterReceiver的一个binder对象,来传递语义。
   
   
     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) {
   
   
     if (ordered) {
   
   
     r.receiver = null;
   
   
     r.curFilter = null;
   
   
     filter.receiverList.curBroadcast = null;
   
   
     if (filter.receiverList.app != null) {
   
   
     filter.receiverList.app.curReceiver = null;
   
   
     }
   
   
     }
   
   
     }
   
   
     }
   
   
     }
   
  

    然后调用BroadcastQueue的performReceiveLocked做进一步的处理。

   
    
      private static 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) {// app 是注册广播接收器的Activity所在的进程记录块.
    
    
      if (app.thread != null) {// 此处由于是动态注册的一般进程都是很好的存在的。
    
    
      app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
    
    
      data, extras, ordered, sticky, sendingUser, app.repProcState); 
    
    
      } else {
    
    
      throw new RemoteException("app.thread must not be null");
    
    
      }
    
    
      } else {
    
    
      receiver.performReceive(intent, resultCode, data, extras, ordered,
    
    
      sticky, sendingUser);
    
    
      }
    
    
      }
    
   

    上述代码的ProcessRecord的thread对象是ApplicationThread类,存在于ActivityThread类当中。

    

  
   
     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是IIntentReceiver对象就是我么你前面传过来的,也就是动态注册是生成的。
   
   
     receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
   
   
     sticky, sendingUser);
   
   
     }
   
  

     下面就继续走到LoadedApk中的ReceiverDispatcher类中的InnerReceiver内部类当中。调用performReceive。这个方法主要的就是调用了ReceiverDispatcher的performReceive方法。我们接着分析ReceiverDispatcher的
performReceive。     

  
   
     public void performReceive(Intent intent, int resultCode, String data,
   
   
     Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
   
   
     //Args 是LoadedApk中的ReceiverDispatcher一个内部类实现了Runnable接口。
   
   
     Args args = new Args(intent, resultCode, data, extras, ordered, 
   
   
     sticky, sendingUser);
   
   
     //mActivityThread 这就是那个ActivityTherad中的H对象调用post所以放到Args的run方法中执行了。
   
   
     if (!mActivityThread.post(args)) { 
   
   
     if (mRegistered && ordered) {// 如果是有序的。
   
   
     IActivityManager mgr = ActivityManagerNative.getDefault();
   
   
     if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
   
   
     "Finishing sync broadcast to " + mReceiver);
   
   
     args.sendFinished(mgr);//发送完成本次广播处理,用来进行下次的广播处理。
   
   
     }
   
   
     }
   
   
     }
   
  

   
  上述代码有一个地方我们最后在分析一下,那就是args.sendFinished(mgr),此处是用于有序广播循环处理的。  
    
接下来直接看Args的run方法。

   
    
     public void run() {
    
    
      //此处这个mReceiver很关键,它是ReceiverDispatcher的成员变量mReceiver
    
    
      //它是在注册时在构造中被初始化的,就是我们新建的要注册的额那个receiver。
    
    
      final BroadcastReceiver receiver = mReceiver; 
    
    
      final boolean ordered = mOrdered;
    
    
      
    
    
      final IActivityManager mgr = ActivityManagerNative.getDefault();
    
    
      final Intent intent = mCurIntent;
    
    
      mCurIntent = null;
    
    
      Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
    
    
      try {
    
    
      ClassLoader cl = mReceiver.getClass().getClassLoader();
    
    
      intent.setExtrasClassLoader(cl);
    
    
      setExtrasClassLoader(cl);
    
    
      receiver.setPendingResult(this);
    
    
      //至此终于调用到了我们写的receiver的onReceive方法
    
    
             //mContext ReceiverDispatcher的成员变量,在构造中传入的context。 
    
    
      //是前面在ContextImpl注册的时候调用
     registerReceiverInternal传入的,ContextImpl实例,也就是当前动态注册的Activcity的上下文
    
    
      //这块不是很确定是当前应用的application的上下文,还是当前activity的上下文?
    
    
      receiver.onReceive(mContext, intent);
    
    
      } catch (Exception e) {
    
    
      }
    
    
      if (receiver.getPendingResult() != null) {
    
    
      finish();
    
    
      }
    
    
      Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    
    
     }
    
   

       此方法中有个一般都注意不到的点,关于receiver怎么实例化的那?动态注册的来说就很简单,就是我们在自己的代码中new的,然后传入到注册的方法的参数当中,最终在ConTextImpl去getReceiverDispatcher,进而实例化
ReceiverDispatcher,并传入到它的mReceiver当中。那么静态的怎么实例化的那?我们
下面慢慢分析。
至此关于
deliverToRegisteredReceiverLocked处理动态注册的receiver完毕(对应于
BroadcastFilter).


       接下来分析用于处理静态注册的receiver的BroadcastQueue中的
processCurBroadcastLocked方法。
  

  
   
     private final void processCurBroadcastLocked(BroadcastRecord r, 
   
   
     ProcessRecord app) throws RemoteException {
   
   
     if (app.thread == null) {
   
   
     throw new RemoteException();
   
   
     }
   
   
     r.receiver = app.thread.asBinder();
   
   
     r.curApp = app;
   
   
     app.curReceiver = r;
   
   
     app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER); //更新进程的状态。
   
   
     mService.updateLruProcessLocked(app, false, null); // 处理一下内存
   
   
     mService.updateOomAdjLocked();
   
   
     
   
   
     //此处告诉是那个receiver,对应于我门前面在processNextBroadcast中对静态的处理。
   
   
     r.intent.setComponent(r.curComponent);
   
   
     
   
   
     boolean started = false;
   
   
     try {
   
   
     mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
   
   
     //下面这个方法又调用到了ActivityThread中的ApplicationThread中对应的方法。
   
   
     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);
   
   
     started = true;
   
   
     } finally {
   
   
     if (!started) {
   
   
     if (DEBUG_BROADCAST) Slog.v(TAG,
   
   
     "Process cur broadcast " + r + ": NOT STARTED!");
   
   
     r.receiver = null;
   
   
     r.curApp = null;
   
   
     app.curReceiver = null;
   
   
     }
   
   
     }
   
   
     }
   
  

    接下来继续看相应的scheduleReceiver方法。

   
    
     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 extends BroadcastReceiver.PendingResult
    
    
      ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
    
    
      sync, false, mAppThread.asBinder(), sendingUser);
    
    
      r.info = info;
    
    
      r.compatInfo = compatInfo;
    
    
      //内部类ApplicationThread,直接调用外部类的方法,最终调用到H类的sendMessage
    
    
      sendMessage(H.RECEIVER, r);
    
    
     }
    
   

    然后就会走到H类的handleMessage方法的case RECEIVER:节点下面

    

  
   
        case RECEIVER:
   
   
     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
   
   
     handleReceiver((ReceiverData)msg.obj);
   
   
     maybeSnapshot();
   
   
     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   
   
     break;
   
  

    调用handleReceiver做最后的处理,并把前面封装的ReceiverData传入。

   
    
      private void handleReceiver(ReceiverData data) {
    
    
      
    
    
      //这个最初就是在processNextBroadcast处理静态注册的ResolveInfo时,new的ComponentName。
    
    
      String component = data.intent.getComponent().getClassName();
    
    
      
    
    
      LoadedApk packageInfo = getPackageInfoNoCheck(
    
    
      data.info.applicationInfo, data.compatInfo);
    
    
      
    
    
      IActivityManager mgr = ActivityManagerNative.getDefault();
    
    
      
    
    
      BroadcastReceiver receiver;
    
    
      try {
    
    
      java.lang.ClassLoader cl = packageInfo.getClassLoader();
    
    
      data.intent.setExtrasClassLoader(cl);
    
    
      data.intent.prepareToEnterProcess();
    
    
      data.setExtrasClassLoader(cl);
    
    
      //此处静态的receiver的实例化,通过反射实例化类。
    
    
      receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
    
    
      } catch (Exception e) {
    
    
      }
    
    
      
    
    
      try {
    
    
      Application app = packageInfo.makeApplication(false, mInstrumentation);
    
    
      
    
    
      ContextImpl context = (ContextImpl)app.getBaseContext();
    
    
      sCurrentBroadcastIntent.set(data.intent);
    
    
      receiver.setPendingResult(data);
    
    
      //调用相应receiver的onReceive方法。有个需要注意的点,这个context的传入。
    
    
      //静态注册的把app的context封装了一下,ReceiverRestrictedContext extends ContextWrapper。
    
    
      receiver.onReceive(context.getReceiverRestrictedContext(),data.intent);
    
    
      } catch (Exception e) {
    
    
      } finally {
    
    
      sCurrentBroadcastIntent.set(null);
    
    
      }
    
    
      
    
    
      if (receiver.getPendingResult() != null) {
    
    
      data.finish();//此处也是用于有序广播的循环,因为静态注册的广播哦都是要串行处理的,此处不需要做是否是ordered的判断
    
    
      }
    
    
      }
    
   

    注意一下静态的实例化方式和传入的context就可以。至此算是完成了
processCurBroadcastLocked的实现分析,动态注册的顾杨波最终调用到LoadedApk中的performReceive,进而调用Args的run方法执行,静态注册的广播最终调用到Activity的handleReceiver方法中进行执行
那么,广播的处理流程到这里也就告一段落,下面分析我们前面你到的有序广播的循环。

5、有序广播的循环处理。     此处的有序广播不是指发出来的是有序广播,而是看在BroadcastQueue中的mOrderedBroadcasts中的广播。

    对于动态注册的有序广播,看前面分析的流程,在执行到ReceiverDispatcher的performReceive时候,如果是有序的,会调用Args的sendFinished的方法。

    而Args继承于BroadcastReceiver.PendingResult。也就是调用到它下面的
sendFinished。

    

  
   
     public void sendFinished(IActivityManager am) {
   
   
     synchronized (this) {
   
   
     
   
   
     mFinished = true;
   
   
     try {
   
   
     if (mResultExtras != null) {
   
   
     mResultExtras.setAllowFds(false);
   
   
     }
   
   
     //最终调用传入的am的finishReceiver,也就是AMS的finishReceiver,去做进一步的处理
   
   
     if (mOrderedHint) {
   
   
     am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras,
   
   
     mAbortBroadcast);
   
   
     } else {
   
   
     am.finishReceiver(mToken, 0, null, null, false);
   
   
     }
   
   
     } catch (RemoteException ex) {
   
   
     }
   
   
     }
   
   
     }
   
  

    AMS中的finishReceiver如下
    

  
   
     public void finishReceiver(IBinder who, int resultCode, String resultData,
   
   
     Bundle resultExtras, boolean resultAbort) {
   
   
     
   
   
     final long origId = Binder.clearCallingIdentity();
   
   
     try {
   
   
     boolean doNext = false;
   
   
     BroadcastRecord r;
   
   
     synchronized(this) {
   
   
     r = broadcastRecordForReceiverLocked(who);
   
   
     if (r != null) {
   
   
     //r.state == BroadcastRecord.APP_RECEIVE || r.state == BroadcastRecord.CALL_DONE_RECEIVE符合要求那么就会返回true。
   
   
     doNext = r.queue.finishReceiverLocked(r, resultCode,
   
   
     resultData, resultExtras, resultAbort, true);
   
   
     }
   
   
     }
   
   
     //如果返回true,那么就调用processNextBroadcast进行下一个receiver的处理。
   
   
     if (doNext) {
   
   
     r.queue.processNextBroadcast(false);
   
   
     }
   
   
     trimApplications();
   
   
     } finally {
   
   
     Binder.restoreCallingIdentity(origId);
   
   
     }
   
   
     }
   
  

    对于静态注册的有序广播也一样,在最后调用handleReceiver做完最后处理时,调用ReceiverData的finish()方法去通知AMS,做进一步处理。而
ReceiverData
也是继承BroadcastReceiver.PendingResult,也就是最终调用到
PendingResult的
finish。

   
    
      public final void finish() {
    
    
      if (mType == TYPE_COMPONENT) {
    
    
      final IActivityManager mgr = ActivityManagerNative.getDefault();
    
    
      if (QueuedWork.hasPendingWork()) {
    
    
      QueuedWork.singleThreadExecutor().execute( new Runnable() {
    
    
      @Override public void run() {
    
    
      if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
    
    
      "Finishing broadcast after work to component " + mToken);
    
    
      sendFinished(mgr);
    
    
      }
    
    
      });
    
    
      } else {
    
    
      if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
    
    
      "Finishing broadcast to component " + mToken);
    
    
      sendFinished(mgr);
    
    
      }
    
    
      } else if (mOrderedHint && mType != TYPE_UNREGISTERED) {
    
    
      final IActivityManager mgr = ActivityManagerNative.getDefault();
    
    
      //再次调用sendFinished向AMS通告receiver已经处理好了,去做进一步的处理
    
    
      sendFinished(mgr); 
    
    
      }
    
    
      }
    
   

    再往下的操作就是上面那我们分析的动态注册的sendFinished的方法啦。至此有序广播就一个个的循环起来了。

6、总结。     广播机制的分析就到此结束了,此文章包含了很多从网上借鉴过来的知识点,加上了自己的分析和理解。下面贴出来参考的大神的文章的路径:

    
http://my.oschina.net/youranhongcha/blog/226274    大神的博客名字:
悠然红茶    十分感谢您的开源精神,此
 如文章只是用于自己的学
    习记录,如
文章您觉得抄袭严重,即刻删除。
    下面贴出一些疑问,欢迎大家解答。(由于工作原因,新项目来了,暂时没时间继续研究了)
    遗留问题:     
    1、静态注册和动态注册 如何实现的排序?在此文章我们直接通过接口获得,而没有去进一步分析。

    
    2、4.0以后,系统广播是不会发送给没有启动的app的 ?只是看到加了一个flag。而没有具体分析实现的原理。

    
    3、发送广播过程中的权限的处理?此文章完全跳过了发送广播时对权限的一些判断。

        4、对AMS的成员变量的mReceiverResolver的理解?     
    5、pid的问题,在静态注册时,新的进程启动完毕后进入到attachApplication时候,获得的pid。然后            if (!badApp && isPendingBroadcastProcessLocked(pid))判断这个pid,难道新启动的一个进程的pid和以前会是一样            的吗?个人对这个不太理解。         6、Context的问题。            自己对Context理解不深,用倒是会用,只是为什么需要用context等等一些问题都不清楚。此处的问题是在LoadedApk            中的成员变量mReceivers,它的key = 上下文Context。那么这个Context是当前Activity的还是整个应用的?后面找时            间依次分析一下。     

 
             

    原文作者:宇你有源丶
    原文地址: https://blog.csdn.net/zy00000000001/article/details/52366693
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞