廣播的注冊讨盒、發(fā)送原理流程

本次源碼基于Android11分析

相關(guān)源碼:

/frameworks/base/core/java/android/content/ContextWrapper.java
/frameworks/base/core/java/android/app/ContextImpl.java
/frameworks/base/core/java/android/app/LoadedApk.java
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
/frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
/frameworks/base/core/java/android/app/ActivityThread.java

廣播的注冊

廣播的注冊分為:靜態(tài)注冊和動態(tài)注冊。靜態(tài)注冊是在AndroidManifest文件中注冊廣播接收器BroadcastReceiver和intent-filter,然后在安裝的時候通過PKMS進行解析存谎。動態(tài)注冊則通過Context.registerReceiver向AMS注冊廣播接收器BroadcastReceiver和IntentFilter。

  • 通過繼承BroadcastReceiver創(chuàng)建一個廣播接收器
class MyBroadcastReceiver : BroadcastReceiver() {

  override fun onReceive(p0: Context?, p1: Intent?) {
  }

}
  • 靜態(tài)注冊廣播接收器
          <receiver
              android:name=".MyBroadcastReceiver"
              android:enabled="true"
              android:exported="true">
              <intent-filter>
                  <action android:name="com.example.blogBroadcasts.MY_BROADCAS" />
              </intent-filter>
          </receiver>
    
  • 動態(tài)注冊廣播接收器
// 動態(tài)注冊廣播
val intentFilter = IntentFilter(ACTION)
val broadcastReceiver = MyBroadcastReceiver()
registerReceiver(broadcastReceiver, intentFilter)

以下講講動態(tài)注冊廣播接收器的過程:

動態(tài)注冊廣播接收器

動態(tài)注冊是把BroadcastReceiver包裝成一個Binder對象肥隆,然后創(chuàng)建一個包含BroadcastReceiver和IntentFilter的BroadcastFilter對象既荚,然后把BroadcastFilter對象加入到AMS的mReceiverResolver變量中。動態(tài)的注冊的大致流程圖如下:

通過Context的注冊處理:

public class ContextWrapper extends Context {

  Context mBase;

  @Override
  public Intent registerReceiver(
          BroadcastReceiver receiver, IntentFilter filter) {
      // 調(diào)用ContextImpl.registerReceiver()方法
      return mBase.registerReceiver(receiver, filter);
  }

  @Override
  public Intent registerReceiver(
          BroadcastReceiver receiver, IntentFilter filter, int flags) {
      return mBase.registerReceiver(receiver, filter, flags);
  }

  @Override
  public Intent registerReceiver(
          BroadcastReceiver receiver, IntentFilter filter,
          String broadcastPermission, Handler scheduler) {
      return mBase.registerReceiver(receiver, filter, broadcastPermission,
              scheduler);
  }

  @Override
  public Intent registerReceiver(
          BroadcastReceiver receiver, IntentFilter filter,
          String broadcastPermission, Handler scheduler, int flags) {
      return mBase.registerReceiver(receiver, filter, broadcastPermission,
              scheduler, flags);
  }

}

class ContextImpl extends Context {

  final LoadedApk mPackageInfo;

  @Override
  public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
      return registerReceiver(receiver, filter, null, null);
  }

  @Override
  public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
                                 int flags) {
      return registerReceiver(receiver, filter, null, null, flags);
  }

  @Override
  public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
                                 String broadcastPermission, Handler scheduler) {
      // 最后調(diào)用registerReceiverInternal()方法
      return registerReceiverInternal(receiver, getUserId(),
              filter, broadcastPermission, scheduler, getOuterContext(), 0);
  }

  @Override
  public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
                                 String broadcastPermission, Handler scheduler, int flags) {
      // 最后調(diào)用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 {
          // 調(diào)用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();
      }
  }

}

public final class LoadedApk {

  public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
                                               Context context, Handler handler,
                                               Instrumentation instrumentation, boolean registered) {
      synchronized (mReceivers) {
          // 先嘗試從緩存中獲取恰聘,緩存中沒有則new一個
          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;
          // 獲取內(nèi)部類Binder對象
          return rd.getIIntentReceiver();
      }
  }

  static final class ReceiverDispatcher {

      final IIntentReceiver.Stub mIIntentReceiver;
      final BroadcastReceiver mReceiver;
      @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
      final Context mContext;
      final Handler mActivityThread;
      final Instrumentation mInstrumentation;
      final boolean mRegistered;
      final IntentReceiverLeaked mLocation;
      RuntimeException mUnregisterLocation;
      boolean mForgotten;

      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();
      }

      // 獲取InnerReceiver的Binder類
      IIntentReceiver getIIntentReceiver() {
          return mIIntentReceiver;
      }

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


  }


}

BroadcastReceiver包裝成一個Binder對象,用于與AMS的回調(diào)通信吸占,最后調(diào)用AMS.registerReceiverWithFeature方法晴叨。

AMS處理動態(tài)注冊廣播

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) {
          // 根據(jù)IntentReceiver查看緩存中是否有ReceiverList
          ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
          // 創(chuàng)建一個新的ReceiverList,并把IntentReceiver傳入其中
          if (rl == null) {
              rl = new ReceiverList(this, callerApp, callingPid, callingUid,
                      userId, receiver);
              mRegisteredReceivers.put(receiver.asBinder(), rl); // 增加到緩存中
          }
          // 創(chuàng)建一個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;
      }
  }

}

registerReceiverWithFeature方法中省略了很多代碼兼蕊,主要代碼中就是創(chuàng)建一個有IntentFilter和IntentReceiverBroadcastFilter對象,然后將BroadcastFilter對象加入到AMS的變量mReceiverResolver中件蚕。

廣播的發(fā)送

廣播的發(fā)送是通過Activity/Service的Context的sendBroadcast孙技、sendOrderedBroadcast方法將Intent發(fā)送廣播:

  val intent = Intent(this, MyBroadcastReceiver::class.java)
  intent.action = ACTION
  sendBroadcast(intent)

Context處理廣播發(fā)送

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);                                                  
  }                                                                                                     
}                                                                                                         
                                                                                                        
class ContextImpl extends Context {                                                                       
                                                                                                        
  public void sendBroadcast(Intent intent) {                                                            
      warnIfCallingFromSystemProcess();                                                                 
      String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());                           
      try {                                                                                             
          intent.prepareToLeaveProcess(this);                                                           
          // 調(diào)用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();                                                            
      }                                                                                                 
  }                                                                                                     
                                                                                                        
  @Override                                                                                             
  public void sendBroadcast(Intent intent, String receiverPermission) {                                 
      warnIfCallingFromSystemProcess();                                                                 
      String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());                           
      String[] receiverPermissions = receiverPermission == null ? null                                  
              : new String[]{receiverPermission};                                                       
      try {                                                                                             
          intent.prepareToLeaveProcess(this);                                                           
          ActivityManager.getService().broadcastIntentWithFeature(                                      
                  mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,        
                  null, Activity.RESULT_OK, null, null, receiverPermissions,                            
                  AppOpsManager.OP_NONE, null, false, false, getUserId());                              
      } catch (RemoteException e) {                                                                     
          throw e.rethrowFromSystemServer();                                                            
      }                                                                                                 
  }                                                                                                     
                                                                                                        
}                                                                                                         
                                                                                                       

最后調(diào)用AMSbroadcastIntentWithFeature方法。

AMS處理發(fā)送廣播

我們發(fā)送廣播的類型可分為:無序廣播(并行)排作、有序廣播(有序)绪杏。對于動態(tài)注冊的廣播接收器如果接收到的是并行廣播則并行執(zhí)行,如果是串行廣播則串行執(zhí)行纽绍。如果是靜態(tài)注冊的工廣播接收器則無論發(fā)送的廣播是否為并行還是串行蕾久,都按串行執(zhí)行。

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);
          }
      }
  }


  @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拌夏,則廣播不會發(fā)送給已停止的package
      intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
      //...
      // ...廣播權(quán)限驗證
      // ... 處理系統(tǒng)相關(guān)廣播
      // ...增加sticky廣播

      // 通過Intent查詢到對應(yīng)的廣播接收器
      List receivers = null; // 靜態(tài)廣播接收器
      List<BroadcastFilter> registeredReceivers = null; //動態(tài)廣播接收器
      //當允許靜態(tài)接收者處理該廣播僧著,則通過PKMS根據(jù)Intent查詢相應(yīng)的靜態(tài)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 {
              // 查詢相應(yīng)的動態(tài)注冊的廣播
              registeredReceivers = mReceiverResolver.queryIntent(intent,
                      resolvedType, false, userId);
          }
      }

      int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
      // 處理并行廣播,并且只給動態(tài)廣播接收器并行處理
      if (!ordered && NR > 0) {
          // 根據(jù)Intent查詢是前臺還是后臺BroadcastQueue
          final BroadcastQueue queue = broadcastQueueForIntent(intent);
          // 創(chuàng)建一個BroadcastRecord障簿,參數(shù)有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);
              // 執(zhí)行隊列
              queue.scheduleBroadcastsLocked();
          }
          // 如果是并行廣播盹愚,執(zhí)行完成后動態(tài)廣播接收器清空處理
          registeredReceivers = null;
          NR = 0;
      }

      //...

      //如果此時registeredReceivers不為null,則表明這是一個串行廣播
      // 則將registeredReceivers合并到receivers一起執(zhí)行串行處理
      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執(zhí)行串行廣播
      if ((receivers != null && receivers.size() > 0)
              || resultTo != null) {
          //根據(jù)intent的flag來判斷前臺隊列或者后臺隊列
          BroadcastQueue queue = broadcastQueueForIntent(intent);
          //創(chuàng)建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();
          }
      }

      return ActivityManager.BROADCAST_SUCCESS;
  }

}                                                                    
                                                                                                                                

AMSbroadcastIntentLocked方法中

  • 通過IntentPKMSAMS. mReceiverResolver變量查詢到對應(yīng)的廣播接收器站故,其中變量receivers存儲靜態(tài)接收器皆怕,registeredReceivers變量存儲動態(tài)接收器。
  • 如果發(fā)送的是并行廣播西篓,則查看是否有對應(yīng)的動態(tài)廣播接收器愈腾,并創(chuàng)建一個擁有Intent和registeredReceivers的BroadcastRecord對象,并保存在BroadcastQueue.mParallelBroadcasts變量中岂津,最終執(zhí)行queue.scheduleBroadcastsLocked()處理廣播虱黄,并把registeredReceivers信息置null。
  • 如果此時registeredReceivers不為null吮成,說明發(fā)送的是串行廣播橱乱,則把registeredReceivers合并到receivers變量辜梳,一起串行執(zhí)行。
  • 對receivers進行串行執(zhí)行泳叠,創(chuàng)建一個擁有Intent和receivers的BroadcastRecord對象作瞄,并保存到隊列的mOrderedBroadcasts變量中,最終執(zhí)行queue.scheduleBroadcastsLocked()處理廣播危纫。

BroadcastQueue處理廣播

public final class BroadcastQueue {


  public void scheduleBroadcastsLocked() {
      if (mBroadcastsScheduled) {
          return;
      }
      // 發(fā)送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) {
              // 執(zhí)行此消息
              case BROADCAST_INTENT_MSG: {
                  processNextBroadcast(true);
              }
              break;
          }
      }
  }


  final void processNextBroadcast(boolean fromMsg) {
      synchronized (mService) {
          processNextBroadcastLocked(fromMsg, false);
      }
  }

  final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
      BroadcastRecord r;
      //...
      //處理并行廣播
      while (mParallelBroadcasts.size() > 0) {
          //把mParallelBroadcasts隊列的BroadcastRecord執(zhí)行完
          r = mParallelBroadcasts.remove(0);
          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);
              //分發(fā)廣播給已注冊的receiver
              deliverToRegisteredReceiverLocked(r, (BroadcastFilter) target, false, i);
          }
          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;

          //當廣播處理時間超時宗挥,則強制結(jié)束這條廣播
          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) {
                  //...
                  //處理廣播消息消息,調(diào)用到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;
          //設(shè)置廣播超時時間叶摄,發(fā)送BROADCAST_TIMEOUT_MSG
          setBroadcastTimeoutLocked(timeoutTime);
      }

      final BroadcastOptions brOptions = r.options;
       //獲取下一個廣播接收者
      final Object nextReceiver = r.receivers.get(recIdx);

      if (nextReceiver instanceof BroadcastFilter) {
          //對于動態(tài)注冊的廣播接收者属韧,deliverToRegisteredReceiverLocked處理廣播
          BroadcastFilter filter = (BroadcastFilter) nextReceiver;
          deliverToRegisteredReceiverLocked(r, filter, r.ordered);
          if (r.receiver == null || !r.ordered) {
              r.state = BroadcastRecord.IDLE;
              scheduleBroadcastsLocked();
          } else {
              ...
          }
          return;
      }

      //對于靜態(tài)注冊的廣播接收者
      ResolveInfo info = (ResolveInfo) nextReceiver;
      ComponentName component = new ComponentName(
              info.activityInfo.applicationInfo.packageName,
              info.activityInfo.name);
         ...
       //執(zhí)行各種權(quán)限檢測,此處省略蛤吓,當權(quán)限不滿足時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正在執(zhí)行中宵喂,stopped狀態(tài)設(shè)置成false
      AppGlobals.getPackageManager().setPackageStoppedState(
              r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid));
      //該receiver所對應(yīng)的進程已經(jīng)運行,則直接處理
      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失敗則重置狀態(tài)
              return;
          }
      }

      //該receiver所對應(yīng)的進程尚未啟動会傲,則創(chuàng)建該進程
      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) {
          //創(chuàng)建失敗锅棕,則結(jié)束該receiver
          finishReceiverLocked(r, r.resultCode, r.resultData,
                  r.resultExtras, r.resultAbort, false);
          scheduleBroadcastsLocked();
          r.state = BroadcastRecord.IDLE;
          return;
      }
      mPendingBroadcast = r;
      mPendingBroadcastRecvIndex = recIdx;
      //...
  }

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

      //...
  }

  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) {
          // 如果ProcessRecord != null,且ApplicationThread不為空
          if (app.thread != null) {
              try {
                  // 調(diào)用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);
      }
  }

}

BroadcastQueue就是將隊列中列表拿出來執(zhí)行淌山,最后調(diào)用app.thread.scheduleRegisteredReceiver對廣播進行回調(diào)裸燎。

回調(diào)廣播

private class ApplicationThread extends IApplicationThread.Stub {

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

}

public final class LoadedApk {

  static final class ReceiverDispatcher {

      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) {
                  // 調(diào)用ReceiverDispatcher的performReceive方法
                  rd.performReceive(intent, resultCode, data, extras,
                          ordered, sticky, sendingUser);
              }
              //...
          }
      }

      // ReceiverDispatcher的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);
          //...
          // 通過Handler執(zhí)行args的Runnable
          if (intent == null || !mActivityThread.post(args.getRunnable())) {
              if (mRegistered && ordered) {
                  IActivityManager mgr = ActivityManager.getService();

                  args.sendFinished(mgr);
              }
          }
      }

      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);
                      // 調(diào)用BroadcastReceiver的onReceive方法
                      receiver.onReceive(mContext, intent);
                  } catch (Exception e) {
                      //...
                  }

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


  }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市泼疑,隨后出現(xiàn)的幾起案子德绿,更是在濱河造成了極大的恐慌,老刑警劉巖退渗,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件移稳,死亡現(xiàn)場離奇詭異,居然都是意外死亡会油,警方通過查閱死者的電腦和手機个粱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來翻翩,“玉大人都许,你說我怎么就攤上這事∩┒常” “怎么了胶征?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長絮吵。 經(jīng)常有香客問我弧烤,道長,這世上最難降的妖魔是什么蹬敲? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任暇昂,我火速辦了婚禮,結(jié)果婚禮上伴嗡,老公的妹妹穿的比我還像新娘急波。我一直安慰自己,他們只是感情好瘪校,可當我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布澄暮。 她就那樣靜靜地躺著,像睡著了一般阱扬。 火紅的嫁衣襯著肌膚如雪泣懊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天麻惶,我揣著相機與錄音馍刮,去河邊找鬼。 笑死窃蹋,一個胖子當著我的面吹牛卡啰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播警没,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼匈辱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了杀迹?” 一聲冷哼從身側(cè)響起亡脸,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎树酪,沒想到半個月后浅碾,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡嗅回,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年及穗,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绵载。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡埂陆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出娃豹,到底是詐尸還是另有隱情焚虱,我是刑警寧澤,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布懂版,位于F島的核電站鹃栽,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏躯畴。R本人自食惡果不足惜民鼓,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一薇芝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧丰嘉,春花似錦夯到、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至路幸,卻和暖如春荐开,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背简肴。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工晃听, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人着帽。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓杂伟,卻偏偏與公主長得像,于是被迫代替她去往敵國和親仍翰。 傳聞我的和親對象是個殘疾皇子赫粥,可洞房花燭夜當晚...
    茶點故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內(nèi)容