廣播的注冊(cè)、發(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

廣播的注冊(cè)

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

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

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

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

以下講講動(dòng)態(tài)注冊(cè)廣播接收器的過(guò)程:

動(dòng)態(tài)注冊(cè)廣播接收器

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

通過(guò)Context的注冊(cè)處理:

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存儲(chǔ)到LoadedApk.ReceiverDispatcher對(duì)象里,
      // 并通過(guò)LoadedApk.ReceiverDispatcher.InnerReceiver的Binder對(duì)象和AMS進(jìn)行通信
      if (receiver != null) {
          if (mPackageInfo != null && context != null) {
              if (scheduler == null) {
                  scheduler = mMainThread.getHandler();
              }
              // 獲取IntentReceiver Binder對(duì)象
              rd = mPackageInfo.getReceiverDispatcher(
                      receiver, context, scheduler,
                      mMainThread.getInstrumentation(), true);
          } else {
              if (scheduler == null) {
                  scheduler = mMainThread.getHandler();
              }
              // 獲取IntentReceiver Binder對(duì)象
              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) {
          // 先嘗試從緩存中獲取,緩存中沒(méi)有則new一個(gè)
          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對(duì)象
          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包裝成一個(gè)Binder對(duì)象,用于與AMS的回調(diào)通信,最后調(diào)用AMS.registerReceiverWithFeature方法。

AMS處理動(dòng)態(tài)注冊(cè)廣播

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)建一個(gè)新的ReceiverList,并把IntentReceiver傳入其中
          if (rl == null) {
              rl = new ReceiverList(this, callerApp, callingPid, callingUid,
                      userId, receiver);
              mRegisteredReceivers.put(receiver.asBinder(), rl); // 增加到緩存中
          }
          // 創(chuàng)建一個(gè)BroadcastFilter對(duì)象,并把ReceiverList對(duì)象和IntentFilter對(duì)象傳入其中
          BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, callerFeatureId,
                  permission, callingUid, userId, instantApp, visibleToInstantApps);
          // 向ReceiverList對(duì)象增加BroadcastFilter對(duì)象
          rl.add(bf);
          // 向mReceiverResolver變量增加BroadcastFilter對(duì)象
          mReceiverResolver.addFilter(bf);
          
          // ...
          return sticky;
      }
  }

}

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

廣播的發(fā)送

廣播的發(fā)送是通過(guò)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ā)送廣播的類型可分為:無(wú)序廣播(并行)、有序廣播(有序)。對(duì)于動(dòng)態(tài)注冊(cè)的廣播接收器如果接收到的是并行廣播則并行執(zhí)行,如果是串行廣播則串行執(zhí)行。如果是靜態(tài)注冊(cè)的工廣播接收器則無(wú)論發(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,則廣播不會(huì)發(fā)送給已停止的package
      intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
      //...
      // ...廣播權(quán)限驗(yàn)證
      // ... 處理系統(tǒng)相關(guān)廣播
      // ...增加sticky廣播

      // 通過(guò)Intent查詢到對(duì)應(yīng)的廣播接收器
      List receivers = null; // 靜態(tài)廣播接收器
      List<BroadcastFilter> registeredReceivers = null; //動(dòng)態(tài)廣播接收器
      //當(dāng)允許靜態(tài)接收者處理該廣播,則通過(guò)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)的動(dòng)態(tài)注冊(cè)的廣播
              registeredReceivers = mReceiverResolver.queryIntent(intent,
                      resolvedType, false, userId);
          }
      }

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

      //...

      //如果此時(shí)registeredReceivers不為null,則表明這是一個(gè)串行廣播
      // 則將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來(lái)判斷前臺(tái)隊(duì)列或者后臺(tái)隊(duì)列
          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加入到有序廣播隊(duì)列
              queue.enqueueOrderedBroadcastLocked(r);
              //處理廣播
              queue.scheduleBroadcastsLocked();
          }
      }

      return ActivityManager.BROADCAST_SUCCESS;
  }

}                                                                    
                                                                                                                                

AMSbroadcastIntentLocked方法中

  • 通過(guò)IntentPKMSAMS. mReceiverResolver變量查詢到對(duì)應(yīng)的廣播接收器,其中變量receivers存儲(chǔ)靜態(tài)接收器,registeredReceivers變量存儲(chǔ)動(dòng)態(tài)接收器。
  • 如果發(fā)送的是并行廣播,則查看是否有對(duì)應(yīng)的動(dòng)態(tài)廣播接收器,并創(chuàng)建一個(gè)擁有Intent和registeredReceivers的BroadcastRecord對(duì)象,并保存在BroadcastQueue.mParallelBroadcasts變量中,最終執(zhí)行queue.scheduleBroadcastsLocked()處理廣播,并把registeredReceivers信息置null。
  • 如果此時(shí)registeredReceivers不為null,說(shuō)明發(fā)送的是串行廣播,則把registeredReceivers合并到receivers變量,一起串行執(zhí)行。
  • 對(duì)receivers進(jìn)行串行執(zhí)行,創(chuàng)建一個(gè)擁有Intent和receivers的BroadcastRecord對(duì)象,并保存到隊(duì)列的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隊(duì)列的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ā)廣播給已注冊(cè)的receiver
              deliverToRegisteredReceiverLocked(r, (BroadcastFilter) target, false, i);
          }
          addBroadcastToHistoryLocked(r);
      }

      // 處理當(dāng)前有序廣播
      do {
          // 獲取BroadcastRecord
          final long now = SystemClock.uptimeMillis();
          r = mDispatcher.getNextBroadcastLocked(now);

          //沒(méi)有更多的廣播等待處理
          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;

          //當(dāng)廣播處理時(shí)間超時(shí),則強(qiáng)制結(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);


      //獲取下一個(gè)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è)置廣播超時(shí)時(shí)間,發(fā)送BROADCAST_TIMEOUT_MSG
          setBroadcastTimeoutLocked(timeoutTime);
      }

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

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

      //對(duì)于靜態(tài)注冊(cè)的廣播接收者
      ResolveInfo info = (ResolveInfo) nextReceiver;
      ComponentName component = new ComponentName(
              info.activityInfo.applicationInfo.packageName,
              info.activityInfo.name);
         ...
       //執(zhí)行各種權(quán)限檢測(cè),此處省略,當(dāng)權(quán)限不滿足時(shí)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所對(duì)應(yīng)的進(jìn)程已經(jīng)運(yùn)行,則直接處理
      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; //啟動(dòng)receiver失敗則重置狀態(tài)
              return;
          }
      }

      //該receiver所對(duì)應(yīng)的進(jìn)程尚未啟動(dòng),則創(chuàng)建該進(jìn)程
      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就是將隊(duì)列中列表拿出來(lái)執(zhí)行,最后調(diào)用app.thread.scheduleRegisteredReceiver對(duì)廣播進(jìn)行回調(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);
          //...
          // 通過(guò)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)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容