Android学习笔记 - 广播的注册与接收

目录

一、简介

二、广播接收器的注册


一、简介

广播是Android四大组件之一,是以intent为媒介在组件间进行传播数据的一种机制。

从整体来看,广播主要有三个动作和三个角色。三个动作包含“注册广播接收器”、“发送广播”和“接收广播”;三个动作包含发送方、接收方和中间人。三者关系如下图:

AMS在其中就是扮演"中间人"的角色。Receiver向AMS注册广播,AMS需要将所有必要的信息以一定的形式记录下来,当Sender发送广播以后,AMS根据广播的信息从数据容器中找到注册该广播的Receiver的信息。此外AMS还要对一些特殊情况进行处理,例如:广播是否被及时消费,如果超时会产生ANR等。


二、广播的注册

实际上,广播的注册最终是由AMS实现的,receiver只需要提供要注册信息(例如:需要监听的广播)即可。

下面列表中的信息便是receiver从AMS中获取到的信息:

广播的注册分为静态注册和动态注册两种注册方式。

静态注册就是在AndroidManifest文件中注册广播接收器相关信息(BroadcastReceiver和intent-filter),然后在应用安装的时候通过PKMS(PackageManagerService)进行解析,来完成注册。

动态注册是把BroadcastReceiver包装成一个Binder对象,然后创建一个包含BroadcastReceiver和IntentFilter的BroadcastFilter对象,最后将BroadcastFilter对象加入到AMS中的mReceiverResolver变量中。具体流程请看下图:

  • 当我们需要动态注册广播时,需要调用Context的registerReceiver方法,然后在ContextWrapper的registerReceiver中调用ContextImpl的registerReceiverInternal方法,最终调用其registerReceiver方法。
  @Override
  public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
                                 String broadcastPermission, Handler scheduler, int flags) {
      // 最后调用registerReceiverInternal()方法
      return registerReceiverInternal(receiver, getUserId(),
              filter, broadcastPermission, scheduler, getOuterContext(), flags);
  }

  private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
                                          IntentFilter filter, String broadcastPermission,
                                          Handler scheduler, Context context, int flags) {
      IIntentReceiver rd = null;
      // 将BroadcastReceiver存储到LoadedApk.ReceiverDispatcher对象里,
      // 并通过LoadedApk.ReceiverDispatcher.InnerReceiver的Binder对象和AMS进行通信
      if (receiver != null) {
          if (mPackageInfo != null && context != null) {
              if (scheduler == null) {
                  scheduler = mMainThread.getHandler();
              }
              // 获取IntentReceiver Binder对象
              rd = mPackageInfo.getReceiverDispatcher(
                      receiver, context, scheduler,
                      mMainThread.getInstrumentation(), true);
          } else {
              if (scheduler == null) {
                  scheduler = mMainThread.getHandler();
              }
              // 获取IntentReceiver Binder对象
              rd = new LoadedApk.ReceiverDispatcher(
                      receiver, context, scheduler, null, true).getIIntentReceiver();
          }
      }
      try {
          // 调用AMS.registerReceiverWithFeature
          final Intent intent = ActivityManager.getService().registerReceiverWithFeature(
                  mMainThread.getApplicationThread(), mBasePackageName, getAttributionTag(), rd,
                  filter, broadcastPermission, userId, flags);
          if (intent != null) {
              intent.setExtrasClassLoader(getClassLoader());
              intent.prepareToEnterProcess();
          }
          return intent;
      } catch (RemoteException e) {
          throw e.rethrowFromSystemServer();
      }
  }

}
  • 在ContextImpl的registerReceiverInternal方法中,通过LoadedApk类型的mPackageInfo对象的getReceiverDispatcher方法来获取IIntentReceiver类型的rd对象,用于广播的跨进程服务。然后调用AMS的registerReceiverWithFeature方法,并将rd对象作为参数传入。
public class ActivityManagerService extends IActivityManager.Stub {

  public Intent registerReceiverWithFeature(IApplicationThread caller, String callerPackage,
                                            String callerFeatureId, IIntentReceiver receiver, IntentFilter filter,
                                            String permission, int userId, int flags) {
      //...
      synchronized (this) {
          // 根据IntentReceiver查看缓存中是否有ReceiverList
          ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
          // 创建一个新的ReceiverList,并把IntentReceiver传入其中
          if (rl == null) {
              rl = new ReceiverList(this, callerApp, callingPid, callingUid,
                      userId, receiver);
              mRegisteredReceivers.put(receiver.asBinder(), rl); // 增加到缓存中
          }
          // 创建一个BroadcastFilter对象,并把ReceiverList对象和IntentFilter对象传入其中
          BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, callerFeatureId,
                  permission, callingUid, userId, instantApp, visibleToInstantApps);
          // 向ReceiverList对象增加BroadcastFilter对象
          rl.add(bf);
          // 向mReceiverResolver变量增加BroadcastFilter对象
          mReceiverResolver.addFilter(bf);
          
          // ...
          return sticky;
      }
  }

}

在AMS的registerReceiverWithFeature方法中首先获取ReceiverList集合,该集合用于存储广播接收器,然后再创建一个用于描述注册的广播接收器,并添加到ReceiverList中,最后将BroadcastFilter添加到mReceiverResolver中,这样AMS接收到广播时就可以从mReceiverResolver中找到对应的广播接收者。


三、广播的发送

广播可以发出多种类型:

普通广播(无序广播):使用sendBroadcast发送的广播,这种广播可以依次传递到各个处理器处理。

有序广播:使用sendOrderedBroadcast发送广播。这种广播在处理器端的处理顺序是按照处理器的不同优先级来区分的,高优先级的处理器会优先解获这个信息,并且可以将这个信息删除。

粘性广播:使用sendStickyBroadcast发送广播。粘性广播在发送后就一直存在于系统的消息容器中,等待对应的处理器去处理,如果暂时没有处理器处理这个消息则移植在消息容器中处于等待状态,粘性广播的receiver如果被销毁,那么下次重建时会自动接收到消息数据。

注意:普通广播和粘性广播不能被截获,而有序广播是可以被截获的。

下面是广播发送的流程图:

从图中我们可以看出,广播的发送分为两个部分,分别是ContextImpl --> AMS,AMS --> BroadcastReceiver。

接下来我就以无序广播作为例子进行叙述:

ContextImpl到AMS的调用过程

 当我们需要发送无序广播时,需要调用context的sendBroadcast方法,然后在ContextWrapper的sendBroadcast中调用ContextImpl的sendBroadcast方法,最终调用AMS的broadcastIntentWithFeature方法。

ContextWrapper.sendBroadcast()方法源码:

public class ContextWrapper extends Context {                                                             
                                                                                                        
  Context mBase;                                                                                        
                                                                                                        
  @Override                                                                                             
  public void sendBroadcast(Intent intent) {                                                            
      mBase.sendBroadcast(intent);                                                                      
  }                                                                                                     
                                                                                                        
  @Override                                                                                             
  public void sendBroadcast(Intent intent, String receiverPermission) {                                 
      mBase.sendBroadcast(intent, receiverPermission);                                                  
  }                                                                                                     
}

ContextImpl.sendBroadcast()源码:

class ContextImpl extends Context {                                                                       
                                                                                                        
  public void sendBroadcast(Intent intent) {                                                            
      warnIfCallingFromSystemProcess();                                                                 
      String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());                           
      try {                                                                                             
          intent.prepareToLeaveProcess(this);                                                           
          // 调用AMS的broadcastIntentWithFeature方法                                                         
          ActivityManager.getService().broadcastIntentWithFeature(                                      
                  mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,        
                  null, Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false,       
                  false, getUserId());                                                                  
      } catch (RemoteException e) {                                                                     
          throw e.rethrowFromSystemServer();                                                            
      }                                                                                                 
  }

ContextImpl.sendBroadcast()中最后还是调用了AMS中的broadcastIntentWithFeature()方法。

ActivityManagerService.broadcastIntentWithFeature()源码:

public class ActivityManagerService extends IActivityManager.Stub {

  public final int broadcastIntentWithFeature(IApplicationThread caller, String callingFeatureId,
                                              Intent intent, String resolvedType, IIntentReceiver resultTo,
                                              int resultCode, String resultData, Bundle resultExtras,
                                              String[] requiredPermissions, int appOp, Bundle bOptions,
                                              boolean serialized, boolean sticky, int userId) {
      enforceNotIsolatedCaller("broadcastIntent");
      synchronized (this) {
          intent = verifyBroadcastLocked(intent);

          final ProcessRecord callerApp = getRecordForAppLocked(caller);
          final int callingPid = Binder.getCallingPid();
          final int callingUid = Binder.getCallingUid();

          final long origId = Binder.clearCallingIdentity();
          try {
              return broadcastIntentLocked(callerApp,
                      callerApp != null ? callerApp.info.packageName : null, callingFeatureId,
                      intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
                      requiredPermissions, appOp, bOptions, serialized, sticky,
                      callingPid, callingUid, callingUid, callingPid, userId);
          } finally {
              Binder.restoreCallingIdentity(origId);
          }
      }
  }

在broadcastIntentWithFeature中首先调用verifyBroadcastLocked方法来检验广播的合法性。继而在调用broadcastIntentLocked方法。下面我们先看verifyBroadcastLocked源码。

verifyBroadcastLocked()源码:

final Intent verifyBroadcastLocked(Intent intent) {
	// Refuse possible leaked file descriptors
	if (intent != null && intent.hasFileDescriptors() == true) { //1
		throw new IllegalArgumentException("File descriptors passed in Intent");
	}
	int flags = intent.getFlags(); //2
	if(!mProcessesReady) {
	if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0){ //3
	}else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){ //4
		Slog.e(TAG,"Attempt to launch receivers of broadcast intent " + intent
				+ "before boot completion");
		throw new IllegalStateException("Cannot broadcast before boot completed"');
	}
	}
	if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) !=0) {
		throw new llegalArgumentException(
				Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
	}
	return intent;
}

在注释1验证了intent是否为空和文件描述符;在注释2获取intent中的flag,注释3表示若此时系统正处于启动过程中,判断flag值,若flag为FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT(启动检测时只接受动态注册的广播接收器)则不做处理,如flag为FLAG_RECEIVER_REGISTERED_ONLY(只接受动态注册的广播接收者)则会抛出异常。

broadcastIntentLocked源码:

@GuardedBy("this")
final int broadcastIntentLocked(ProcessRecord callerApp,
                                String callerPackage, String callerFeatureId, 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 realCallingUid,
                                int realCallingPid, int userId) {
    return broadcastIntentLocked(callerApp, callerPackage, callerFeatureId, intent,
            resolvedType, resultTo, resultCode, resultData, resultExtras, requiredPermissions,
            appOp, bOptions, ordered, sticky, callingPid, callingUid, realCallingUid,
            realCallingPid, userId, false /* allowBackgroundActivityStarts */,
            null /*broadcastWhitelist*/);
}

  @GuardedBy("this")
  final int broadcastIntentLocked(ProcessRecord callerApp, String callerPackage,
                                  @Nullable String callerFeatureId, 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 realCallingUid,
                                  int realCallingPid, int userId, boolean allowBackgroundActivityStarts,
                                  @Nullable int[] broadcastWhitelist) {

      intent = new Intent(intent);
      //增加该flag,则广播不会发送给已停止的package
      intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
      //...
      // ...广播权限验证
      // ... 处理系统相关广播
      // ...增加sticky广播

      // 通过Intent查询到对应的广播接收器
      List receivers = null; // 静态广播接收器
      List<BroadcastFilter> registeredReceivers = null; //动态广播接收器
      //当允许静态接收者处理该广播,则通过PKMS根据Intent查询相应的静态receivers
      if ((intent.getFlags() & Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
          receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
      }
      if (intent.getComponent() == null) {
          if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
           ...
          } else {
              // 查询相应的动态注册的广播
              registeredReceivers = mReceiverResolver.queryIntent(intent,
                      resolvedType, false, userId);
          }
      }

      int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
      // 处理并行广播,并且只给动态广播接收器并行处理
      if (!ordered && NR > 0) {
          // 根据Intent查询是前台还是后台BroadcastQueue
          final BroadcastQueue queue = broadcastQueueForIntent(intent);
          // 创建一个BroadcastRecord,参数有Intent和registeredReceivers
          BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage,
                  callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType,
                  requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
                  resultCode, resultData, resultExtras, ordered, sticky, false, userId,
                  allowBackgroundActivityStarts, timeoutExempt);
          if (!replaced) {
              // 将BroadcastRecord加入到mParallelBroadcasts队列
              queue.enqueueParallelBroadcastLocked(r);
              // 执行队列
              queue.scheduleBroadcastsLocked();
          }
          // 如果是并行广播,执行完成后动态广播接收器清空处理
          registeredReceivers = null;
          NR = 0;
      }

      //...

      //如果此时registeredReceivers不为null,则表明这是一个串行广播
      // 则将registeredReceivers合并到receivers一起执行串行处理
      int NT = receivers != null ? receivers.size() : 0;
      int it = 0;
      ResolveInfo curt = null;
      BroadcastFilter curr = null;
      while (it < NT && ir < NR) {
          if (curt == null) {
              curt = (ResolveInfo) receivers.get(it);
          }
          if (curr == null) {
              curr = registeredReceivers.get(ir);
          }
          if (curr.getPriority() >= curt.priority) {
              receivers.add(it, curr);
              ir++;
              curr = null;
              it++;
              NT++;
          } else {
              it++;
              curt = null;
          }
      }
      while (ir < NR) {
          if (receivers == null) {
              receivers = new ArrayList();
          }
          receivers.add(registeredReceivers.get(ir));
          ir++;
      }

      // receivers执行串行广播
      if ((receivers != null && receivers.size() > 0)
              || resultTo != null) {
          //根据intent的flag来判断前台队列或者后台队列
          BroadcastQueue queue = broadcastQueueForIntent(intent); //1
          //创建BroadcastRecord
          BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
                  callerPackage, callingPid, callingUid, resolvedType,
                  requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
                  resultData, resultExtras, ordered, sticky, false, userId);

          boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
          if (!replaced) {
              //将BroadcastRecord加入到有序广播队列
              queue.enqueueOrderedBroadcastLocked(r);
              //处理广播
              queue.scheduleBroadcastsLocked(); //2
          }
      }

      return ActivityManager.BROADCAST_SUCCESS;
  }

在broadcastIntentLocked方法中

  1. 通过intent去packageManagerService和ActivityManagerService.mReceiverResolver变量中查询到对应的广播接收器,其中变量receivers存储静态接收器,registeredReceivers变量存储动态接收器。
  2. 如果发送的是并行广播,则查看是否有对应的动态广播接收器,并创建一个拥有Intent和registeredReceivers的BroadcastRecord对象,并保存在BroadcastQueue.mParallelBroadcasts变量中,最终执行queue.schedulecastsLocked()处理广播,并把registeredReceivers消息制空。
  3. 如果regigteredReceivers不为null, 说明发送的是串行广播,则把registeredReceivers合并到receivers变量,一起串行执行。
  4. 对receivers进行串行执行,创建一个拥有intent和receivers的BroadcastRecord对象,并保存到队列的mOrderedBroadcasts变量中,最终执行queue.scheduleBroadcastsLocked()处理广播。

到这里便是ContextImpl到AMS的全部过程,下面便来看AMS到BroadcastReceiver的调用过程。

AMS到BroadcastReceiver的调用过程

下面先看scheduleBroadcastsLocked()的源码,看它是如何处理广播的。

scheduleBroadcastsLocked()源码:

public final class BroadcastQueue {


  public void scheduleBroadcastsLocked() {
      if (mBroadcastsScheduled) {
          return;
      }
      // 发送BROADCAST_INTENT_MSG类型消息
      mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
      mBroadcastsScheduled = true;

  }
}
  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: {
                  processNextBroadcast(true);
              }
              break;
          }
      }
  }
  final void processNextBroadcast(boolean fromMsg) {
      synchronized (mService) {
          processNextBroadcastLocked(fromMsg, false);
      }
  }

scheduleBroadcastsLocked方法中向scheduleBroadcastsLocked类型的mHandler对象发送了BROADCAST_INTENT_MSG类型的消息,handler在收到这个消息后就调用processNextBroadcast方法进行处理,这个方法对无序广播和有序广播分别进行处理,目的是将广播发送给广播接收者。

processNextBroadcastLocked() 源码:


  final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
      BroadcastRecord r;
      //...
      //处理并行广播
      while (mParallelBroadcasts.size() > 0) { //1
          //把mParallelBroadcasts队列的BroadcastRecord执行完
          r = mParallelBroadcasts.remove(0); //2
          r.dispatchTime = SystemClock.uptimeMillis();
          r.dispatchClockTime = System.currentTimeMillis();
          // r.receivers就是AMS的registeredReceivers变量
          final int N = r.receivers.size();

          for (int i = 0; i < N; i++) {
              Object target = r.receivers.get(i);
              //分发广播给已注册的receiver
              deliverToRegisteredReceiverLocked(r, (BroadcastFilter) target, false, i); \\3
          }
          addBroadcastToHistoryLocked(r);
      }

      // 处理当前有序广播
      do {
          // 获取BroadcastRecord
          final long now = SystemClock.uptimeMillis();
          r = mDispatcher.getNextBroadcastLocked(now);

          //没有更多的广播等待处理
          if (r == null) {
              mDispatcher.scheduleDeferralCheckLocked(false);
              mService.scheduleAppGcsLocked();
              if (looped) {
                  mService.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_START_RECEIVER);
              }
              if (mService.mUserController.mBootCompleted && mLogLatencyMetrics) {
                  mLogLatencyMetrics = false;
              }
              return;
          }

          boolean forceReceive = false;
          // 获取Receivers的大小
          int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;

          //当广播处理时间超时,则强制结束这条广播
          if (mService.mProcessesReady && !r.timeoutExempt && r.dispatchTime > 0) {
              if ((numReceivers > 0) &&
                      (now > r.dispatchTime + (2 * mConstants.TIMEOUT * numReceivers))) {
                  broadcastTimeoutLocked(false); // forcibly finish this broadcast
                  forceReceive = true;
                  r.state = BroadcastRecord.IDLE;
              }
          }
          //...
          if (r.receivers == null || r.nextReceiver >= numReceivers
                  || r.resultAbort || forceReceive) {
              if (r.resultTo != null) {
                  //...
                  //处理广播消息消息,调用到onReceive()
                  performReceiveLocked(r.callerApp, r.resultTo,
                          new Intent(r.intent), r.resultCode,
                          r.resultData, r.resultExtras, false, false, r.userId);
                  //...
              }

              //...
              mDispatcher.retireBroadcastLocked(r);
              r = null;
              looped = true;
              continue;
          }
          //..
      } while (r == null);


      //获取下一个receiver的index
      int recIdx = r.nextReceiver++;

      r.receiverTime = SystemClock.uptimeMillis();
      if (recIdx == 0) {
          r.dispatchTime = r.receiverTime;
          r.dispatchClockTime = System.currentTimeMillis();
      }
      if (!mPendingBroadcastTimeoutMessage) {
          long timeoutTime = r.receiverTime + mTimeoutPeriod;
          //设置广播超时时间,发送BROADCAST_TIMEOUT_MSG
          setBroadcastTimeoutLocked(timeoutTime);
      }

      final BroadcastOptions brOptions = r.options;
       //获取下一个广播接收者
      final Object nextReceiver = r.receivers.get(recIdx);

      if (nextReceiver instanceof BroadcastFilter) {
          //对于动态注册的广播接收者,deliverToRegisteredReceiverLocked处理广播
          BroadcastFilter filter = (BroadcastFilter) nextReceiver;
          deliverToRegisteredReceiverLocked(r, filter, r.ordered);
          if (r.receiver == null || !r.ordered) {
              r.state = BroadcastRecord.IDLE;
              scheduleBroadcastsLocked();
          } else {
              ...
          }
          return;
      }

      //对于静态注册的广播接收者
      ResolveInfo info = (ResolveInfo) nextReceiver;
      ComponentName component = new ComponentName(
              info.activityInfo.applicationInfo.packageName,
              info.activityInfo.name);
         ...
       //执行各种权限检测,此处省略,当权限不满足时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;
      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;
      ...
      //Broadcast正在执行中,stopped状态设置成false
      AppGlobals.getPackageManager().setPackageStoppedState(
              r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid));
      //该receiver所对应的进程已经运行,则直接处理
      ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
              info.activityInfo.applicationInfo.uid, false);
      if (app != null && app.thread != null) {
          try {
              app.addPackage(info.activityInfo.packageName,
                      info.activityInfo.applicationInfo.versionCode, mService.mProcessStats);
              processCurBroadcastLocked(r, app);
              return;
          } catch (RemoteException e) {
          } catch (RuntimeException e) {
              finishReceiverLocked(r, r.resultCode, r.resultData, r.resultExtras, r.resultAbort, false);
              scheduleBroadcastsLocked();
              r.state = BroadcastRecord.IDLE; //启动receiver失败则重置状态
              return;
          }
      }

      //该receiver所对应的进程尚未启动,则创建该进程
      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) {
          //创建失败,则结束该receiver
          finishReceiverLocked(r, r.resultCode, r.resultData,
                  r.resultExtras, r.resultAbort, false);
          scheduleBroadcastsLocked();
          r.state = BroadcastRecord.IDLE;
          return;
      }
      mPendingBroadcast = r;
      mPendingBroadcastRecvIndex = recIdx;
      //...
  }
  • 注释1的mParallelBroadcasts列表用来存储无序广播,通过while循环将mParallelBroadcasts列表中的无序广播发送给对应的广播接收者。
  • 注释2获取每一个mParallelBroadcasts列表中存储的BroadcastRecord类型的r对象。
  • 注释3通过deliverToRegisteredReceiverLocked方法将这些r对象描述的广播发送给对应的广播接收者。

deliverToRegisteredReceiverLocked()源码:

  private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
                                                 BroadcastFilter filter, boolean ordered, int index) {
      //...
      // 调用performReceiveLocked方法
      performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
              new Intent(r.intent), r.resultCode, r.resultData,
              r.resultExtras, r.ordered, r.initialSticky, r.userId);

      //...
  }

这里省去了大部分的代码,这些代码是用来检查广播发送者和广播接收者的权限,如果通过了权限的检测则会调用 performReceiveLocked 方法。

performReceiveLocked()源码:

  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) { \\1
          // 如果ProcessRecord != null,且ApplicationThread不为空
          if (app.thread != null) { \\2
              try {
                  // 调用ApplicationThread.scheduleRegisteredReceiver
                  app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
                          data, extras, ordered, sticky, sendingUser, app.getReportedProcState());
              } catch (RemoteException ex) {
                  synchronized (mService) {
                      app.scheduleCrash("can't deliver broadcast");
                  }
                  throw ex;
              }
          } else {
              // Application has died. Receiver doesn't exist.
              throw new RemoteException("app.thread must not be null");
          }
      } else {
          // 如果ProcessRecord为空
          receiver.performReceive(intent, resultCode, data, extras, ordered,
                  sticky, sendingUser);
      }
  }

注释1和注释2处的代码表示如果广播接收者所在的应用程序进行存在并且正在运行,则执行 scheduleRegisteredReceiver 对广播进行回调。

scheduleRegisteredReceiver()源码:

  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);
      // 调用IntentReceiver的performReceive方法
      receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
              sticky, sendingUser); \\1
  }

注释1处调用了IIntentReceiver类的performReceive方法。这里实现的是LoadedApk.ReceiverDispater.InnerReceiver()

final static class InnerReceiver extends IIntentReceiver.Stub {
          final WeakReference<ReceiverDispatcher> mDispatcher;
          final LoadedApk.ReceiverDispatcher mStrongRef;

          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 (rd != null) {
                  // 调用ReceiverDispatcher的performReceive方法
                  rd.performReceive(intent, resultCode, data, extras,
                          ordered, sticky, sendingUser); //1
              }
              //...
          }
      }

注释1调用了ReceiverDispatcher类的performReceive方法:

performReceive()源码:

     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); //1
          //...
          // 通过Handler执行args的Runnable
          if (intent == null || !mActivityThread.post(args.getRunnable())) { //2
              if (mRegistered && ordered) {
                  IActivityManager mgr = ActivityManager.getService();

                  args.sendFinished(mgr);
              }
          }
      }

注释1将广播的intent等信息封装成为Args对象,并在注释2调用mActivityThread的post方法执行了args的Runnable。这个mActivityThread是一个Handler对象,具体指向的就是H,注释2处的代码就是将args的Runnable通过H发送到主线程的消息队列中。

final class Args extends BroadcastReceiver.PendingResult {

          public final Runnable getRunnable() {
              return () -> {
                  final BroadcastReceiver receiver = mReceiver;
                  //...
                  try {
                      ClassLoader cl = mReceiver.getClass().getClassLoader();
                      intent.setExtrasClassLoader(cl);
                      intent.prepareToEnterProcess();
                      setExtrasClassLoader(cl);
                      receiver.setPendingResult(this);
                      // 调用BroadcastReceiver的onReceive方法
                      receiver.onReceive(mContext, intent); //1
                  } catch (Exception e) {
                      //...
                  }

                  if (receiver.getPendingResult() != null) {
                      finish();
                  }
              };
          }
      }

在注释1执行了广播接收者的onReceive方法,这样注册的广播接收者就收到了广播并得到了intent。

以上便是广播的注册和发送、接收的全部过程了。

猜你喜欢

转载自blog.csdn.net/HaveFun_Wine/article/details/128471652