Android BroadcastReceiver原理剖析
这里主要跟一下android源码,看看BroadcastReceiver的工作原理。BroadcastReceiver分动态注册和静态注册,静态注册涉及到系统开机时的程序安装过程,这里关于静态注册BroadcastReceiver的过程暂时不理,等写到程序安装会有相应的解说。
我们将从普通的Activity.registerReceiver开始:
//android.app.ContextWrapper.java 464 @Override 465 public Intent registerReceiver( 466 BroadcastReceiver receiver, IntentFilter filter) { 467 return mBase.registerReceiver(receiver, filter); 468 }
//android.app.ContextImpl.java 1410 @Override 1411 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 1412 return registerReceiver(receiver, filter, null, null); 1413 } 1414 1415 @Override 1416 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 1417 String broadcastPermission, Handler scheduler) { 1418 return registerReceiverInternal(receiver, getUserId(), 1419 filter, broadcastPermission, scheduler, getOuterContext()); 1420 } 1421 1422 @Override 1423 public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, 1424 IntentFilter filter, String broadcastPermission, Handler scheduler) { 1425 return registerReceiverInternal(receiver, user.getIdentifier(), 1426 filter, broadcastPermission, scheduler, getOuterContext()); 1427 } 1628 private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId, 1629 IntentFilter filter, String broadcastPermission, 1630 Handler scheduler, Context context) { 1631 IIntentReceiver rd = null; 1632 if (receiver != null) { 1633 if (mPackageInfo != null && context != null) { 1634 if (scheduler == null) { 1635 scheduler = mMainThread.getHandler();//如果没有传入Handler scheduler 默认是mMainThread.getHandler() 1636 } 1637 rd = mPackageInfo.getReceiverDispatcher( 1638 receiver, context, scheduler, 1639 mMainThread.getInstrumentation(), true); 1640 } else { 1641 if (scheduler == null) { 1642 scheduler = mMainThread.getHandler();//如果没有传入Handler scheduler 默认是mMainThread.getHandler() 1643 } 1644 rd = new LoadedApk.ReceiverDispatcher( 1645 receiver, context, scheduler, null, true).getIIntentReceiver(); 1646 } 1647 } 1648 try { 1649 return ActivityManagerNative.getDefault().registerReceiver(//注册到 1650 mMainThread.getApplicationThread(), mBasePackageName, 1651 rd, filter, broadcastPermission, userId); 1652 } catch (RemoteException e) { 1653 return null; 1654 } 1655 }
1、Activity继承自ContextWrapper,Activity.registerReceiver最终会跳转到ActivityManagerNative.registerReceiver,中间值得注意的是Handler scheduler,回调的线程调度,这是一个可选的参数,如果不设或者设置为空,默认是主线程。这里会新建一个LoadedApk.ReceiverDispatcher,用于保存receiver+scheduler信息。
//com.android.server.am.ActivityManagerService.java 12764 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12765 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 12766 enforceNotIsolatedCaller("registerReceiver"); 12767 int callingUid; 12768 int callingPid; 12769 synchronized(this) { 12770 ProcessRecord callerApp = null; 12771 if (caller != null) { 12772 callerApp = getRecordForAppLocked(caller); 12773 if (callerApp == null) { 12774 throw new SecurityException( 12775 "Unable to find app for caller " + caller 12776 + " (pid=" + Binder.getCallingPid() 12777 + ") when registering receiver " + receiver); 12778 } 12779 if (callerApp.info.uid != Process.SYSTEM_UID && 12780 !callerApp.pkgList.containsKey(callerPackage)) { 12781 throw new SecurityException("Given caller package " + callerPackage 12782 + " is not running in process " + callerApp); 12783 } 12784 callingUid = callerApp.info.uid; 12785 callingPid = callerApp.pid; 12786 } else { 12787 callerPackage = null; 12788 callingUid = Binder.getCallingUid(); 12789 callingPid = Binder.getCallingPid(); 12790 } 12791 12792 userId = this.handleIncomingUser(callingPid, callingUid, userId, 12793 true, true, "registerReceiver", callerPackage); 12794 12795 List allSticky = null; 12796 12797 // Look for any matching sticky broadcasts... 12798 Iterator actions = filter.actionsIterator(); 12799 if (actions != null) { 12800 while (actions.hasNext()) { 12801 String action = (String)actions.next(); 12802 allSticky = getStickiesLocked(action, filter, allSticky, 12803 UserHandle.USER_ALL); 12804 allSticky = getStickiesLocked(action, filter, allSticky, 12805 UserHandle.getUserId(callingUid)); 12806 } 12807 } else { 12808 allSticky = getStickiesLocked(null, filter, allSticky, 12809 UserHandle.USER_ALL); 12810 allSticky = getStickiesLocked(null, filter, allSticky, 12811 UserHandle.getUserId(callingUid)); 12812 } 12813 12814 // The first sticky in the list is returned directly back to 12815 // the client. 12816 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12817 12818 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12819 + ": " + sticky); 12820 12821 if (receiver == null) { 12822 return sticky; 12823 } 12824 12825 ReceiverList rl 12826 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12827 if (rl == null) { 12828 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 12829 userId, receiver); 12830 if (rl.app != null) { 12831 rl.app.receivers.add(rl); 12832 } else { 12833 try { 12834 receiver.asBinder().linkToDeath(rl, 0); 12835 } catch (RemoteException e) { 12836 return sticky; 12837 } 12838 rl.linkedToDeath = true; 12839 } 12840 mRegisteredReceivers.put(receiver.asBinder(), rl);//注册到HashMap 12841 } else if (rl.uid != callingUid) { 12842 throw new IllegalArgumentException( 12843 "Receiver requested to register for uid " + callingUid 12844 + " was previously registered for uid " + rl.uid); 12845 } else if (rl.pid != callingPid) { 12846 throw new IllegalArgumentException( 12847 "Receiver requested to register for pid " + callingPid 12848 + " was previously registered for pid " + rl.pid); 12849 } else if (rl.userId != userId) { 12850 throw new IllegalArgumentException( 12851 "Receiver requested to register for user " + userId 12852 + " was previously registered for user " + rl.userId); 12853 } 12854 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 12855 permission, callingUid, userId); 12856 rl.add(bf); 12857 if (!bf.debugCheck()) { 12858 Slog.w(TAG, "==> For Dynamic broadast"); 12859 } 12860 mReceiverResolver.addFilter(bf); 12861 12862 // Enqueue broadcasts for all existing stickies that match 12863 // this filter. 12864 if (allSticky != null) { 12865 ArrayList receivers = new ArrayList(); 12866 receivers.add(bf); 12867 12868 int N = allSticky.size(); 12869 for (int i=0; i<N; i++) { 12870 Intent intent = (Intent)allSticky.get(i); 12871 BroadcastQueue queue = broadcastQueueForIntent(intent); 12872 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 12873 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 12874 null, null, false, true, true, -1); 12875 queue.enqueueParallelBroadcastLocked(r); 12876 queue.scheduleBroadcastsLocked(); 12877 } 12878 } 12879 12880 return sticky; 12881 } 12882 }
2、主要看12840:mRegisteredReceivers.put(receiver.asBinder(), rl);queue.enqueueParallelBroadcastLocked(r);//receiver注册到HashMap,receiver被封装成dispatcher注册到BroadcastQueue,到这里BroadcastReceiver的注册基本完毕。
我们从普通的Activity.sendBroadcast继续:
//android.app.ContextImpl.java 1129 @Override 1130 public void sendBroadcast(Intent intent) { 1131 warnIfCallingFromSystemProcess(); 1132 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1133 try { 1134 intent.prepareToLeaveProcess(); 1135 ActivityManagerNative.getDefault().broadcastIntent( 1136 mMainThread.getApplicationThread(), intent, resolvedType, null, 1137 Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, false, 1138 getUserId()); 1139 } catch (RemoteException e) { 1140 } 1141 }
//com.android.server.am.ActivityManagerService.java 13444 public final int broadcastIntent(IApplicationThread caller, 13445 Intent intent, String resolvedType, IIntentReceiver resultTo, 13446 int resultCode, String resultData, Bundle map, 13447 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13448 enforceNotIsolatedCaller("broadcastIntent"); 13449 synchronized(this) { 13450 intent = verifyBroadcastLocked(intent); 13451 13452 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13453 final int callingPid = Binder.getCallingPid(); 13454 final int callingUid = Binder.getCallingUid(); 13455 final long origId = Binder.clearCallingIdentity(); 13456 int res = broadcastIntentLocked(callerApp, 13457 callerApp != null ? callerApp.info.packageName : null, 13458 intent, resolvedType, resultTo, 13459 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13460 callingPid, callingUid, userId); 13461 Binder.restoreCallingIdentity(origId); 13462 return res; 13463 } 13464 } 13019 private final int broadcastIntentLocked(ProcessRecord callerApp, 13020 String callerPackage, Intent intent, String resolvedType, 13021 IIntentReceiver resultTo, int resultCode, String resultData, 13022 Bundle map, String requiredPermission, int appOp, 13023 boolean ordered, boolean sticky, int callingPid, int callingUid, 13024 int userId) { 13025 intent = new Intent(intent); 13026 13027 // By default broadcasts do not go to stopped apps. 13028 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13029 13030 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13031 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13032 + " ordered=" + ordered + " userid=" + userId); 13033 if ((resultTo != null) && !ordered) { 13034 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13035 } 13036 13037 userId = handleIncomingUser(callingPid, callingUid, userId, 13038 true, false, "broadcast", callerPackage); 13039 13040 // Make sure that the user who is receiving this broadcast is started. 13041 // If not, we will just skip it. 13042 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13043 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13044 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13045 Slog.w(TAG, "Skipping broadcast of " + intent 13046 + ": user " + userId + " is stopped"); 13047 return ActivityManager.BROADCAST_SUCCESS; 13048 } 13049 } 13050 13051 /* 13052 * Prevent non-system code (defined here to be non-persistent 13053 * processes) from sending protected broadcasts. 13054 */ 13055 int callingAppId = UserHandle.getAppId(callingUid); 13056 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13057 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13058 callingUid == 0) { 13059 // Always okay. 13060 } else if (callerApp == null || !callerApp.persistent) { 13061 try { 13062 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13063 intent.getAction())) { 13064 String msg = "Permission Denial: not allowed to send broadcast " 13065 + intent.getAction() + " from pid=" 13066 + callingPid + ", uid=" + callingUid; 13067 Slog.w(TAG, msg); 13068 throw new SecurityException(msg); 13069 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13070 // Special case for compatibility: we don't want apps to send this, 13071 // but historically it has not been protected and apps may be using it 13072 // to poke their own app widget. So, instead of making it protected, 13073 // just limit it to the caller. 13074 if (callerApp == null) { 13075 String msg = "Permission Denial: not allowed to send broadcast " 13076 + intent.getAction() + " from unknown caller."; 13077 Slog.w(TAG, msg); 13078 throw new SecurityException(msg); 13079 } else if (intent.getComponent() != null) { 13080 // They are good enough to send to an explicit component... verify 13081 // it is being sent to the calling app. 13082 if (!intent.getComponent().getPackageName().equals( 13083 callerApp.info.packageName)) { 13084 String msg = "Permission Denial: not allowed to send broadcast " 13085 + intent.getAction() + " to " 13086 + intent.getComponent().getPackageName() + " from " 13087 + callerApp.info.packageName; 13088 Slog.w(TAG, msg); 13089 throw new SecurityException(msg); 13090 } 13091 } else { 13092 // Limit broadcast to their own package. 13093 intent.setPackage(callerApp.info.packageName); 13094 } 13095 } 13096 } catch (RemoteException e) { 13097 Slog.w(TAG, "Remote exception", e); 13098 return ActivityManager.BROADCAST_SUCCESS; 13099 } 13100 } 13101 13102 // Handle special intents: if this broadcast is from the package 13103 // manager about a package being removed, we need to remove all of 13104 // its activities from the history stack. 13105 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13106 intent.getAction()); 13107 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13108 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13109 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13110 || uidRemoved) { 13111 if (checkComponentPermission( 13112 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13113 callingPid, callingUid, -1, true) 13114 == PackageManager.PERMISSION_GRANTED) { 13115 if (uidRemoved) { 13116 final Bundle intentExtras = intent.getExtras(); 13117 final int uid = intentExtras != null 13118 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13119 if (uid >= 0) { 13120 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13121 synchronized (bs) { 13122 bs.removeUidStatsLocked(uid); 13123 } 13124 mAppOpsService.uidRemoved(uid); 13125 } 13126 } else { 13127 // If resources are unavailable just force stop all 13128 // those packages and flush the attribute cache as well. 13129 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13130 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13131 if (list != null && (list.length > 0)) { 13132 for (String pkg : list) { 13133 forceStopPackageLocked(pkg, -1, false, true, true, false, userId, 13134 "storage unmount"); 13135 } 13136 sendPackageBroadcastLocked( 13137 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13138 } 13139 } else { 13140 Uri data = intent.getData(); 13141 String ssp; 13142 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13143 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13144 intent.getAction()); 13145 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13146 forceStopPackageLocked(ssp, UserHandle.getAppId( 13147 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13148 false, userId, removed ? "pkg removed" : "pkg changed"); 13149 } 13150 if (removed) { 13151 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13152 new String[] {ssp}, userId); 13153 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13154 mAppOpsService.packageRemoved( 13155 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13156 13157 // Remove all permissions granted from/to this package 13158 removeUriPermissionsForPackageLocked(ssp, userId, true); 13159 } 13160 } 13161 } 13162 } 13163 } 13164 } else { 13165 String msg = "Permission Denial: " + intent.getAction() 13166 + " broadcast from " + callerPackage + " (pid=" + callingPid 13167 + ", uid=" + callingUid + ")" 13168 + " requires " 13169 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13170 Slog.w(TAG, msg); 13171 throw new SecurityException(msg); 13172 } 13173 13174 // Special case for adding a package: by default turn on compatibility 13175 // mode. 13176 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13177 Uri data = intent.getData(); 13178 String ssp; 13179 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13180 mCompatModePackages.handlePackageAddedLocked(ssp, 13181 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13182 } 13183 } 13184 13185 /* 13186 * If this is the time zone changed action, queue up a message that will reset the timezone 13187 * of all currently running processes. This message will get queued up before the broadcast 13188 * happens. 13189 */ 13190 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13191 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13192 } 13193 13194 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13195 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13196 } 13197 13198 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13199 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13200 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13201 } 13202 13203 // Add to the sticky list if requested. 13204 if (sticky) { 13205 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13206 callingPid, callingUid) 13207 != PackageManager.PERMISSION_GRANTED) { 13208 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13209 + callingPid + ", uid=" + callingUid 13210 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13211 Slog.w(TAG, msg); 13212 throw new SecurityException(msg); 13213 } 13214 if (requiredPermission != null) { 13215 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13216 + " and enforce permission " + requiredPermission); 13217 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13218 } 13219 if (intent.getComponent() != null) { 13220 throw new SecurityException( 13221 "Sticky broadcasts can't target a specific component"); 13222 } 13223 // We use userId directly here, since the "all" target is maintained 13224 // as a separate set of sticky broadcasts. 13225 if (userId != UserHandle.USER_ALL) { 13226 // But first, if this is not a broadcast to all users, then 13227 // make sure it doesn't conflict with an existing broadcast to 13228 // all users. 13229 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13230 UserHandle.USER_ALL); 13231 if (stickies != null) { 13232 ArrayList<Intent> list = stickies.get(intent.getAction()); 13233 if (list != null) { 13234 int N = list.size(); 13235 int i; 13236 for (i=0; i<N; i++) { 13237 if (intent.filterEquals(list.get(i))) { 13238 throw new IllegalArgumentException( 13239 "Sticky broadcast " + intent + " for user " 13240 + userId + " conflicts with existing global broadcast"); 13241 } 13242 } 13243 } 13244 } 13245 } 13246 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13247 if (stickies == null) { 13248 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13249 mStickyBroadcasts.put(userId, stickies); 13250 } 13251 ArrayList<Intent> list = stickies.get(intent.getAction()); 13252 if (list == null) { 13253 list = new ArrayList<Intent>(); 13254 stickies.put(intent.getAction(), list); 13255 } 13256 int N = list.size(); 13257 int i; 13258 for (i=0; i<N; i++) { 13259 if (intent.filterEquals(list.get(i))) { 13260 // This sticky already exists, replace it. 13261 list.set(i, new Intent(intent)); 13262 break; 13263 } 13264 } 13265 if (i >= N) { 13266 list.add(new Intent(intent)); 13267 } 13268 } 13269 13270 int[] users; 13271 if (userId == UserHandle.USER_ALL) { 13272 // Caller wants broadcast to go to all started users. 13273 users = mStartedUserArray; 13274 } else { 13275 // Caller wants broadcast to go to one specific user. 13276 users = new int[] {userId}; 13277 } 13278 13279 // Figure out who all will receive this broadcast. 13280 List receivers = null; 13281 List<BroadcastFilter> registeredReceivers = null; 13282 // Need to resolve the intent to interested receivers... 13283 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13284 == 0) { 13285 receivers = collectReceiverComponents(intent, resolvedType, users); 13286 } 13287 if (intent.getComponent() == null) { 13288 registeredReceivers = mReceiverResolver.queryIntent(intent, 13289 resolvedType, false, userId); 13290 } 13291 13292 final boolean replacePending = 13293 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13294 13295 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13296 + " replacePending=" + replacePending); 13297 13298 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13299 if (!ordered && NR > 0) { 13300 // If we are not serializing this broadcast, then send the 13301 // registered receivers separately so they don't wait for the 13302 // components to be launched. 13303 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13304 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13305 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13306 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13307 ordered, sticky, false, userId); 13308 if (DEBUG_BROADCAST) Slog.v( 13309 TAG, "Enqueueing parallel broadcast " + r); 13310 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13311 if (!replaced) { 13312 queue.enqueueParallelBroadcastLocked(r); 13313 queue.scheduleBroadcastsLocked(); 13314 } 13315 registeredReceivers = null; 13316 NR = 0; 13317 } 13318 13319 // Merge into one list. 13320 int ir = 0; 13321 if (receivers != null) { 13322 // A special case for PACKAGE_ADDED: do not allow the package 13323 // being added to see this broadcast. This prevents them from 13324 // using this as a back door to get run as soon as they are 13325 // installed. Maybe in the future we want to have a special install 13326 // broadcast or such for apps, but we'd like to deliberately make 13327 // this decision. 13328 String skipPackages[] = null; 13329 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13330 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13331 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13332 Uri data = intent.getData(); 13333 if (data != null) { 13334 String pkgName = data.getSchemeSpecificPart(); 13335 if (pkgName != null) { 13336 skipPackages = new String[] { pkgName }; 13337 } 13338 } 13339 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13340 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13341 } 13342 if (skipPackages != null && (skipPackages.length > 0)) { 13343 for (String skipPackage : skipPackages) { 13344 if (skipPackage != null) { 13345 int NT = receivers.size(); 13346 for (int it=0; it<NT; it++) { 13347 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13348 if (curt.activityInfo.packageName.equals(skipPackage)) { 13349 receivers.remove(it); 13350 it--; 13351 NT--; 13352 } 13353 } 13354 } 13355 } 13356 } 13357 13358 int NT = receivers != null ? receivers.size() : 0; 13359 int it = 0; 13360 ResolveInfo curt = null; 13361 BroadcastFilter curr = null; 13362 while (it < NT && ir < NR) { 13363 if (curt == null) { 13364 curt = (ResolveInfo)receivers.get(it); 13365 } 13366 if (curr == null) { 13367 curr = registeredReceivers.get(ir); 13368 } 13369 if (curr.getPriority() >= curt.priority) { 13370 // Insert this broadcast record into the final list. 13371 receivers.add(it, curr); 13372 ir++; 13373 curr = null; 13374 it++; 13375 NT++; 13376 } else { 13377 // Skip to the next ResolveInfo in the final list. 13378 it++; 13379 curt = null; 13380 } 13381 } 13382 } 13383 while (ir < NR) { 13384 if (receivers == null) { 13385 receivers = new ArrayList(); 13386 } 13387 receivers.add(registeredReceivers.get(ir)); 13388 ir++; 13389 } 13390 13391 if ((receivers != null && receivers.size() > 0) 13392 || resultTo != null) { 13393 BroadcastQueue queue = broadcastQueueForIntent(intent); 13394 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13395 callerPackage, callingPid, callingUid, resolvedType, 13396 requiredPermission, appOp, receivers, resultTo, resultCode, 13397 resultData, map, ordered, sticky, false, userId); 13398 if (DEBUG_BROADCAST) Slog.v( 13399 TAG, "Enqueueing ordered broadcast " + r 13400 + ": prev had " + queue.mOrderedBroadcasts.size()); 13401 if (DEBUG_BROADCAST) { 13402 int seq = r.intent.getIntExtra("seq", -1); 13403 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13404 } 13405 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13406 if (!replaced) { 13407 queue.enqueueOrderedBroadcastLocked(r); 13408 queue.scheduleBroadcastsLocked(); 13409 } 13410 } 13411 13412 return ActivityManager.BROADCAST_SUCCESS; 13413 }
//com.android.server.am.BroadcastQueue.java 312 public void scheduleBroadcastsLocked() { 313 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts [" 314 + mQueueName + "]: current=" 315 + mBroadcastsScheduled); 316 317 if (mBroadcastsScheduled) { 318 return; 319 } 320 mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this)); 321 mBroadcastsScheduled = true; 322 } 134 final Handler mHandler = new Handler() { 135 public void handleMessage(Message msg) { 136 switch (msg.what) { 137 case BROADCAST_INTENT_MSG: { 138 if (DEBUG_BROADCAST) Slog.v( 139 TAG, "Received BROADCAST_INTENT_MSG"); 140 processNextBroadcast(true); 141 } break; 142 case BROADCAST_TIMEOUT_MSG: { 143 synchronized (mService) { 144 broadcastTimeoutLocked(true); 145 } 146 } break; 147 } 148 } 149 }; 525 final void processNextBroadcast(boolean fromMsg) { 526 synchronized(mService) { 527 BroadcastRecord r; 528 529 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast [" 530 + mQueueName + "]: " 531 + mParallelBroadcasts.size() + " broadcasts, " 532 + mOrderedBroadcasts.size() + " ordered broadcasts"); 533 534 mService.updateCpuStats(); 535 536 if (fromMsg) { 537 mBroadcastsScheduled = false; 538 } 539 540 // First, deliver any non-serialized broadcasts right away. 541 while (mParallelBroadcasts.size() > 0) { 542 r = mParallelBroadcasts.remove(0); 543 r.dispatchTime = SystemClock.uptimeMillis(); 544 r.dispatchClockTime = System.currentTimeMillis(); 545 final int N = r.receivers.size(); 546 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast [" 547 + mQueueName + "] " + r); 548 for (int i=0; i<N; i++) { 549 Object target = r.receivers.get(i); 550 if (DEBUG_BROADCAST) Slog.v(TAG, 551 "Delivering non-ordered on [" + mQueueName + "] to registered " 552 + target + ": " + r); 553 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false); 554 } 555 addBroadcastToHistoryLocked(r); 556 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast [" 557 + mQueueName + "] " + r); 558 } 559 560 // Now take care of the next serialized one... 561 562 // If we are waiting for a process to come up to handle the next 563 // broadcast, then do nothing at this point. Just in case, we 564 // check that the process we're waiting for still exists. 565 if (mPendingBroadcast != null) { 566 if (DEBUG_BROADCAST_LIGHT) { 567 Slog.v(TAG, "processNextBroadcast [" 568 + mQueueName + "]: waiting for " 569 + mPendingBroadcast.curApp); 570 } 571 572 boolean isDead; 573 synchronized (mService.mPidsSelfLocked) { 574 ProcessRecord proc = mService.mPidsSelfLocked.get(mPendingBroadcast.curApp.pid); 575 isDead = proc == null || proc.crashing; 576 } 577 if (!isDead) { 578 // It's still alive, so keep waiting 579 return; 580 } else { 581 Slog.w(TAG, "pending app [" 582 + mQueueName + "]" + mPendingBroadcast.curApp 583 + " died before responding to broadcast"); 584 mPendingBroadcast.state = BroadcastRecord.IDLE; 585 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex; 586 mPendingBroadcast = null; 587 } 588 } 589 590 boolean looped = false; 591 592 do { 593 if (mOrderedBroadcasts.size() == 0) { 594 // No more broadcasts pending, so all done! 595 mService.scheduleAppGcsLocked(); 596 if (looped) { 597 // If we had finished the last ordered broadcast, then 598 // make sure all processes have correct oom and sched 599 // adjustments. 600 mService.updateOomAdjLocked(); 601 } 602 return; 603 } 604 r = mOrderedBroadcasts.get(0); 605 boolean forceReceive = false; 606 607 // Ensure that even if something goes awry with the timeout 608 // detection, we catch "hung" broadcasts here, discard them, 609 // and continue to make progress. 610 // 611 // This is only done if the system is ready so that PRE_BOOT_COMPLETED 612 // receivers don't get executed with timeouts. They're intended for 613 // one time heavy lifting after system upgrades and can take 614 // significant amounts of time. 615 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0; 616 if (mService.mProcessesReady && r.dispatchTime > 0) { 617 long now = SystemClock.uptimeMillis(); 618 if ((numReceivers > 0) && 619 (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) { 620 Slog.w(TAG, "Hung broadcast [" 621 + mQueueName + "] discarded after timeout failure:" 622 + " now=" + now 623 + " dispatchTime=" + r.dispatchTime 624 + " startTime=" + r.receiverTime 625 + " intent=" + r.intent 626 + " numReceivers=" + numReceivers 627 + " nextReceiver=" + r.nextReceiver 628 + " state=" + r.state); 629 broadcastTimeoutLocked(false); // forcibly finish this broadcast 630 forceReceive = true; 631 r.state = BroadcastRecord.IDLE; 632 } 633 } 634 635 if (r.state != BroadcastRecord.IDLE) { 636 if (DEBUG_BROADCAST) Slog.d(TAG, 637 "processNextBroadcast(" 638 + mQueueName + ") called when not idle (state=" 639 + r.state + ")"); 640 return; 641 } 642 643 if (r.receivers == null || r.nextReceiver >= numReceivers 644 || r.resultAbort || forceReceive) { 645 // No more receivers for this broadcast! Send the final 646 // result if requested... 647 if (r.resultTo != null) { 648 try { 649 if (DEBUG_BROADCAST) { 650 int seq = r.intent.getIntExtra("seq", -1); 651 Slog.i(TAG, "Finishing broadcast [" 652 + mQueueName + "] " + r.intent.getAction() 653 + " seq=" + seq + " app=" + r.callerApp); 654 } 655 performReceiveLocked(r.callerApp, r.resultTo, 656 new Intent(r.intent), r.resultCode, 657 r.resultData, r.resultExtras, false, false, r.userId); 658 // Set this to null so that the reference 659 // (local and remote) isn't kept in the mBroadcastHistory. 660 r.resultTo = null; 661 } catch (RemoteException e) { 662 Slog.w(TAG, "Failure [" 663 + mQueueName + "] sending broadcast result of " 664 + r.intent, e); 665 } 666 } 667 668 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG"); 669 cancelBroadcastTimeoutLocked(); 670 671 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast " 672 + r); 673 674 // ... and on to the next... 675 addBroadcastToHistoryLocked(r); 676 mOrderedBroadcasts.remove(0); 677 r = null; 678 looped = true; 679 continue; 680 } 681 } while (r == null); 682 683 // Get the next receiver... 684 int recIdx = r.nextReceiver++; 685 686 // Keep track of when this receiver started, and make sure there 687 // is a timeout message pending to kill it if need be. 688 r.receiverTime = SystemClock.uptimeMillis(); 689 if (recIdx == 0) { 690 r.dispatchTime = r.receiverTime; 691 r.dispatchClockTime = System.currentTimeMillis(); 692 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast [" 693 + mQueueName + "] " + r); 694 } 695 if (! mPendingBroadcastTimeoutMessage) { 696 long timeoutTime = r.receiverTime + mTimeoutPeriod; 697 if (DEBUG_BROADCAST) Slog.v(TAG, 698 "Submitting BROADCAST_TIMEOUT_MSG [" 699 + mQueueName + "] for " + r + " at " + timeoutTime); 700 setBroadcastTimeoutLocked(timeoutTime); 701 } 702 703 Object nextReceiver = r.receivers.get(recIdx); 704 if (nextReceiver instanceof BroadcastFilter) { 705 // Simple case: this is a registered receiver who gets 706 // a direct call. 707 BroadcastFilter filter = (BroadcastFilter)nextReceiver; 708 if (DEBUG_BROADCAST) Slog.v(TAG, 709 "Delivering ordered [" 710 + mQueueName + "] to registered " 711 + filter + ": " + r); 712 deliverToRegisteredReceiverLocked(r, filter, r.ordered); 713 if (r.receiver == null || !r.ordered) { 714 // The receiver has already finished, so schedule to 715 // process the next one. 716 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing [" 717 + mQueueName + "]: ordered=" 718 + r.ordered + " receiver=" + r.receiver); 719 r.state = BroadcastRecord.IDLE; 720 scheduleBroadcastsLocked(); 721 } 722 return; 723 } 724 725 // Hard case: need to instantiate the receiver, possibly 726 // starting its application process to host it. 727 728 ResolveInfo info = 729 (ResolveInfo)nextReceiver; 730 ComponentName component = new ComponentName( 731 info.activityInfo.applicationInfo.packageName, 732 info.activityInfo.name); 733 734 boolean skip = false; 735 int perm = mService.checkComponentPermission(info.activityInfo.permission, 736 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid, 737 info.activityInfo.exported); 738 if (perm != PackageManager.PERMISSION_GRANTED) { 739 if (!info.activityInfo.exported) { 740 Slog.w(TAG, "Permission Denial: broadcasting " 741 + r.intent.toString() 742 + " from " + r.callerPackage + " (pid=" + r.callingPid 743 + ", uid=" + r.callingUid + ")" 744 + " is not exported from uid " + info.activityInfo.applicationInfo.uid 745 + " due to receiver " + component.flattenToShortString()); 746 } else { 747 Slog.w(TAG, "Permission Denial: broadcasting " 748 + r.intent.toString() 749 + " from " + r.callerPackage + " (pid=" + r.callingPid 750 + ", uid=" + r.callingUid + ")" 751 + " requires " + info.activityInfo.permission 752 + " due to receiver " + component.flattenToShortString()); 753 } 754 skip = true; 755 } 756 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID && 757 r.requiredPermission != null) { 758 try { 759 perm = AppGlobals.getPackageManager(). 760 checkPermission(r.requiredPermission, 761 info.activityInfo.applicationInfo.packageName); 762 } catch (RemoteException e) { 763 perm = PackageManager.PERMISSION_DENIED; 764 } 765 if (perm != PackageManager.PERMISSION_GRANTED) { 766 Slog.w(TAG, "Permission Denial: receiving " 767 + r.intent + " to " 768 + component.flattenToShortString() 769 + " requires " + r.requiredPermission 770 + " due to sender " + r.callerPackage 771 + " (uid " + r.callingUid + ")"); 772 skip = true; 773 } 774 } 775 if (r.appOp != AppOpsManager.OP_NONE) { 776 int mode = mService.mAppOpsService.noteOperation(r.appOp, 777 info.activityInfo.applicationInfo.uid, info.activityInfo.packageName); 778 if (mode != AppOpsManager.MODE_ALLOWED) { 779 if (DEBUG_BROADCAST) Slog.v(TAG, 780 "App op " + r.appOp + " not allowed for broadcast to uid " 781 + info.activityInfo.applicationInfo.uid + " pkg " 782 + info.activityInfo.packageName); 783 skip = true; 784 } 785 } 786 if (!skip) { 787 skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid, 788 r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid); 789 } 790 boolean isSingleton = false; 791 try { 792 isSingleton = mService.isSingleton(info.activityInfo.processName, 793 info.activityInfo.applicationInfo, 794 info.activityInfo.name, info.activityInfo.flags); 795 } catch (SecurityException e) { 796 Slog.w(TAG, e.getMessage()); 797 skip = true; 798 } 799 if ((info.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 800 if (ActivityManager.checkUidPermission( 801 android.Manifest.permission.INTERACT_ACROSS_USERS, 802 info.activityInfo.applicationInfo.uid) 803 != PackageManager.PERMISSION_GRANTED) { 804 Slog.w(TAG, "Permission Denial: Receiver " + component.flattenToShortString() 805 + " requests FLAG_SINGLE_USER, but app does not hold " 806 + android.Manifest.permission.INTERACT_ACROSS_USERS); 807 skip = true; 808 } 809 } 810 if (r.curApp != null && r.curApp.crashing) { 811 // If the target process is crashing, just skip it. 812 Slog.w(TAG, "Skipping deliver ordered [" + mQueueName + "] " + r 813 + " to " + r.curApp + ": process crashing"); 814 skip = true; 815 } 816 817 if (skip) { 818 if (DEBUG_BROADCAST) Slog.v(TAG, 819 "Skipping delivery of ordered [" 820 + mQueueName + "] " + r + " for whatever reason"); 821 r.receiver = null; 822 r.curFilter = null; 823 r.state = BroadcastRecord.IDLE; 824 scheduleBroadcastsLocked(); 825 return; 826 } 827 828 r.state = BroadcastRecord.APP_RECEIVE; 829 String targetProcess = info.activityInfo.processName; 830 r.curComponent = component; 831 if (r.callingUid != Process.SYSTEM_UID && isSingleton) { 832 info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0); 833 } 834 r.curReceiver = info.activityInfo; 835 if (DEBUG_MU && r.callingUid > UserHandle.PER_USER_RANGE) { 836 Slog.v(TAG_MU, "Updated broadcast record activity info for secondary user, " 837 + info.activityInfo + ", callingUid = " + r.callingUid + ", uid = " 838 + info.activityInfo.applicationInfo.uid); 839 } 840 841 // Broadcast is being executed, its package can't be stopped. 842 try { 843 AppGlobals.getPackageManager().setPackageStoppedState( 844 r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid)); 845 } catch (RemoteException e) { 846 } catch (IllegalArgumentException e) { 847 Slog.w(TAG, "Failed trying to unstop package " 848 + r.curComponent.getPackageName() + ": " + e); 849 } 850 851 // Is this receiver's application already running? 852 ProcessRecord app = mService.getProcessRecordLocked(targetProcess, 853 info.activityInfo.applicationInfo.uid, false); 854 if (app != null && app.thread != null) { 855 try { 856 app.addPackage(info.activityInfo.packageName, mService.mProcessStats); 857 processCurBroadcastLocked(r, app); 858 return; 859 } catch (RemoteException e) { 860 Slog.w(TAG, "Exception when sending broadcast to " 861 + r.curComponent, e); 862 } catch (RuntimeException e) { 863 Log.wtf(TAG, "Failed sending broadcast to " 864 + r.curComponent + " with " + r.intent, e); 865 // If some unexpected exception happened, just skip 866 // this broadcast. At this point we are not in the call 867 // from a client, so throwing an exception out from here 868 // will crash the entire system instead of just whoever 869 // sent the broadcast. 870 logBroadcastReceiverDiscardLocked(r); 871 finishReceiverLocked(r, r.resultCode, r.resultData, 872 r.resultExtras, r.resultAbort, false); 873 scheduleBroadcastsLocked(); 874 // We need to reset the state if we failed to start the receiver. 875 r.state = BroadcastRecord.IDLE; 876 return; 877 } 878 879 // If a dead object exception was thrown -- fall through to 880 // restart the application. 881 } 882 883 // Not running -- get it started, to be executed when the app comes up. 884 if (DEBUG_BROADCAST) Slog.v(TAG, 885 "Need to start app [" 886 + mQueueName + "] " + targetProcess + " for broadcast " + r); 887 if ((r.curApp=mService.startProcessLocked(targetProcess, 888 info.activityInfo.applicationInfo, true, 889 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND, 890 "broadcast", r.curComponent, 891 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false)) 892 == null) { 893 // Ah, this recipient is unavailable. Finish it if necessary, 894 // and mark the broadcast record as ready for the next. 895 Slog.w(TAG, "Unable to launch app " 896 + info.activityInfo.applicationInfo.packageName + "/" 897 + info.activityInfo.applicationInfo.uid + " for broadcast " 898 + r.intent + ": process is bad"); 899 logBroadcastReceiverDiscardLocked(r); 900 finishReceiverLocked(r, r.resultCode, r.resultData, 901 r.resultExtras, r.resultAbort, false); 902 scheduleBroadcastsLocked(); 903 r.state = BroadcastRecord.IDLE; 904 return; 905 } 906 907 mPendingBroadcast = r; 908 mPendingBroadcastRecvIndex = recIdx; 909 } 910 }
到这里其实开始走两个分支,1,如果是动态注册的receiver,其实可以知道,运行进程是活的,接收对象是存在的,deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false),2,如果是静态注册的receiver,运行进程不确定是否存活,接收对象不存在,如果进程未拉起,mService.startProcessLocked(),启动接收进程然后继续scheduleBroadcastsLocked()循环,下次进入processCurBroadcastLocked(r, app)。既如果目标进程未启动,这里是会拉起来的。如果进程已启动,则processCurBroadcastLocked(r, app)分发广播。
第一个分支:
//com.android.server.am.BroadcastQueue.java 429 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r, 430 BroadcastFilter filter, boolean ordered) { 431 boolean skip = false; 432 if (filter.requiredPermission != null) { 433 int perm = mService.checkComponentPermission(filter.requiredPermission, 434 r.callingPid, r.callingUid, -1, true); 435 if (perm != PackageManager.PERMISSION_GRANTED) { 436 Slog.w(TAG, "Permission Denial: broadcasting " 437 + r.intent.toString() 438 + " from " + r.callerPackage + " (pid=" 439 + r.callingPid + ", uid=" + r.callingUid + ")" 440 + " requires " + filter.requiredPermission 441 + " due to registered receiver " + filter); 442 skip = true; 443 } 444 } 445 if (!skip && r.requiredPermission != null) { 446 int perm = mService.checkComponentPermission(r.requiredPermission, 447 filter.receiverList.pid, filter.receiverList.uid, -1, true); 448 if (perm != PackageManager.PERMISSION_GRANTED) { 449 Slog.w(TAG, "Permission Denial: receiving " 450 + r.intent.toString() 451 + " to " + filter.receiverList.app 452 + " (pid=" + filter.receiverList.pid 453 + ", uid=" + filter.receiverList.uid + ")" 454 + " requires " + r.requiredPermission 455 + " due to sender " + r.callerPackage 456 + " (uid " + r.callingUid + ")"); 457 skip = true; 458 } 459 } 460 if (r.appOp != AppOpsManager.OP_NONE) { 461 int mode = mService.mAppOpsService.noteOperation(r.appOp, 462 filter.receiverList.uid, filter.packageName); 463 if (mode != AppOpsManager.MODE_ALLOWED) { 464 if (DEBUG_BROADCAST) Slog.v(TAG, 465 "App op " + r.appOp + " not allowed for broadcast to uid " 466 + filter.receiverList.uid + " pkg " + filter.packageName); 467 skip = true; 468 } 469 } 470 if (!skip) { 471 skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid, 472 r.callingPid, r.resolvedType, filter.receiverList.uid); 473 } 474 475 if (filter.receiverList.app == null || filter.receiverList.app.crashing) { 476 Slog.w(TAG, "Skipping deliver [" + mQueueName + "] " + r 477 + " to " + filter.receiverList + ": process crashing"); 478 skip = true; 479 } 480 481 if (!skip) { 482 // If this is not being sent as an ordered broadcast, then we 483 // don't want to touch the fields that keep track of the current 484 // state of ordered broadcasts. 485 if (ordered) { 486 r.receiver = filter.receiverList.receiver.asBinder(); 487 r.curFilter = filter; 488 filter.receiverList.curBroadcast = r; 489 r.state = BroadcastRecord.CALL_IN_RECEIVE; 490 if (filter.receiverList.app != null) { 491 // Bump hosting application to no longer be in background 492 // scheduling class. Note that we can't do that if there 493 // isn't an app... but we can only be in that case for 494 // things that directly call the IActivityManager API, which 495 // are already core system stuff so don't matter for this. 496 r.curApp = filter.receiverList.app; 497 filter.receiverList.app.curReceiver = r; 498 mService.updateOomAdjLocked(r.curApp, true); 499 } 500 } 501 try { 502 if (DEBUG_BROADCAST_LIGHT) { 503 int seq = r.intent.getIntExtra("seq", -1); 504 Slog.i(TAG, "Delivering to " + filter 505 + " (seq=" + seq + "): " + r); 506 } 507 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver, 508 new Intent(r.intent), r.resultCode, r.resultData, 509 r.resultExtras, r.ordered, r.initialSticky, r.userId); 510 if (ordered) { 511 r.state = BroadcastRecord.CALL_DONE_RECEIVE; 512 } 513 } catch (RemoteException e) { 514 Slog.w(TAG, "Failure sending broadcast " + r.intent, e); 515 if (ordered) { 516 r.receiver = null; 517 r.curFilter = null; 518 filter.receiverList.curBroadcast = null; 519 if (filter.receiverList.app != null) { 520 filter.receiverList.app.curReceiver = null; 521 } 522 } 523 } 524 } 525 } 414 private static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver, 415 Intent intent, int resultCode, String data, Bundle extras, 416 boolean ordered, boolean sticky, int sendingUser) throws RemoteException { 417 // Send the intent to the receiver asynchronously using one-way binder calls. 418 if (app != null && app.thread != null) { 419 // If we have an app thread, do the call through that so it is 420 // correctly ordered with other one-way calls. 421 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, 422 data, extras, ordered, sticky, sendingUser, app.repProcState); 423 } else { 424 receiver.performReceive(intent, resultCode, data, extras, ordered, 425 sticky, sendingUser); 426 } 427 }
接着切换到ActivityThread
//android.app.ActivityThread.java 812 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, 813 int resultCode, String dataStr, Bundle extras, boolean ordered, 814 boolean sticky, int sendingUser, int processState) throws RemoteException { 815 updateProcessState(processState, false); 816 receiver.performReceive(intent, resultCode, dataStr, extras, ordered, 817 sticky, sendingUser); 818 }
接着切换到ReceiverDispatcher.IntentReceiver/ReceiverDispatcher
//android.app.LoadedApk.java 666 final static class InnerReceiver extends IIntentReceiver.Stub { 667 final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher; 668 final LoadedApk.ReceiverDispatcher mStrongRef; 669 670 InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) { 671 mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd); 672 mStrongRef = strong ? rd : null; 673 } 674 public void performReceive(Intent intent, int resultCode, String data, 675 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 676 LoadedApk.ReceiverDispatcher rd = mDispatcher.get(); 677 if (ActivityThread.DEBUG_BROADCAST) { 678 int seq = intent.getIntExtra("seq", -1); 679 Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction() + " seq=" + seq 680 + " to " + (rd != null ? rd.mReceiver : null)); 681 } 682 if (rd != null) { 683 rd.performReceive(intent, resultCode, data, extras, 684 ordered, sticky, sendingUser); 685 } else { 686 // The activity manager dispatched a broadcast to a registered 687 // receiver in this process, but before it could be delivered the 688 // receiver was unregistered. Acknowledge the broadcast on its 689 // behalf so that the system's broadcast sequence can continue. 690 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG, 691 "Finishing broadcast to unregistered receiver"); 692 IActivityManager mgr = ActivityManagerNative.getDefault(); 693 try { 694 if (extras != null) { 695 extras.setAllowFds(false); 696 } 697 mgr.finishReceiver(this, resultCode, data, extras, false); 698 } catch (RemoteException e) { 699 Slog.w(ActivityThread.TAG, "Couldn't finish broadcast to unregistered receiver"); 700 } 701 } 702 } 703 } 834 public void performReceive(Intent intent, int resultCode, String data, 835 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 836 if (ActivityThread.DEBUG_BROADCAST) { 837 int seq = intent.getIntExtra("seq", -1); 838 Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction() + " seq=" + seq 839 + " to " + mReceiver); 840 } 841 Args args = new Args(intent, resultCode, data, extras, ordered, 842 sticky, sendingUser); 843 if (!mActivityThread.post(args)) { 844 if (mRegistered && ordered) { 845 IActivityManager mgr = ActivityManagerNative.getDefault(); 846 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG, 847 "Finishing sync broadcast to " + mReceiver); 848 args.sendFinished(mgr); 849 } 850 } 851 } 715 final class Args extends BroadcastReceiver.PendingResult implements Runnable { 716 private Intent mCurIntent; 717 private final boolean mOrdered; 718 719 public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras, 720 boolean ordered, boolean sticky, int sendingUser) { 721 super(resultCode, resultData, resultExtras, 722 mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, 723 ordered, sticky, mIIntentReceiver.asBinder(), sendingUser); 724 mCurIntent = intent; 725 mOrdered = ordered; 726 } 727 728 public void run() { 729 final BroadcastReceiver receiver = mReceiver; 730 final boolean ordered = mOrdered; 731 732 if (ActivityThread.DEBUG_BROADCAST) { 733 int seq = mCurIntent.getIntExtra("seq", -1); 734 Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction() 735 + " seq=" + seq + " to " + mReceiver); 736 Slog.i(ActivityThread.TAG, " mRegistered=" + mRegistered 737 + " mOrderedHint=" + ordered); 738 } 739 740 final IActivityManager mgr = ActivityManagerNative.getDefault(); 741 final Intent intent = mCurIntent; 742 mCurIntent = null; 743 744 if (receiver == null || mForgotten) { 745 if (mRegistered && ordered) { 746 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG, 747 "Finishing null broadcast to " + mReceiver); 748 sendFinished(mgr); 749 } 750 return; 751 } 752 753 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg"); 754 try { 755 ClassLoader cl = mReceiver.getClass().getClassLoader(); 756 intent.setExtrasClassLoader(cl); 757 setExtrasClassLoader(cl); 758 receiver.setPendingResult(this); 759 receiver.onReceive(mContext, intent); 760 } catch (Exception e) { 761 if (mRegistered && ordered) { 762 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG, 763 "Finishing failed broadcast to " + mReceiver); 764 sendFinished(mgr); 765 } 766 if (mInstrumentation == null || 767 !mInstrumentation.onException(mReceiver, e)) { 768 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 769 throw new RuntimeException( 770 "Error receiving broadcast " + intent 771 + " in " + mReceiver, e); 772 } 773 } 774 775 if (receiver.getPendingResult() != null) { 776 finish(); 777 } 778 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 779 } 780 }
3、在这里使用传入的handler(如果注册的时候没有传入,默认是主线程)post到相应的线程run,最后执行onReceive。
第二个分支:
//com.android.server.am.BroadcastQueue.java
212 private final void processCurBroadcastLocked(BroadcastRecord r, 213 ProcessRecord app) throws RemoteException { 214 if (DEBUG_BROADCAST) Slog.v(TAG, 215 "Process cur broadcast " + r + " for app " + app); 216 if (app.thread == null) { 217 throw new RemoteException(); 218 } 219 r.receiver = app.thread.asBinder(); 220 r.curApp = app; 221 app.curReceiver = r; 222 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER); 223 mService.updateLruProcessLocked(app, true, false); 224 225 // Tell the application to launch this receiver. 226 r.intent.setComponent(r.curComponent); 227 228 boolean started = false; 229 try { 230 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, 231 "Delivering to component " + r.curComponent 232 + ": " + r); 233 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 234 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver, 235 mService.compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo), 236 r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId, 237 app.repProcState); 238 if (DEBUG_BROADCAST) Slog.v(TAG, 239 "Process cur broadcast " + r + " DELIVERED for app " + app); 240 started = true; 241 } finally { 242 if (!started) { 243 if (DEBUG_BROADCAST) Slog.v(TAG, 244 "Process cur broadcast " + r + ": NOT STARTED!"); 245 r.receiver = null; 246 r.curApp = null; 247 app.curReceiver = null; 248 } 249 } 250 }
切换binder进程
//android.app.ActivityThread.java 653 public final void scheduleReceiver(Intent intent, ActivityInfo info, 654 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras, 655 boolean sync, int sendingUser, int processState) { 656 updateProcessState(processState, false); 657 ReceiverData r = new ReceiverData(intent, resultCode, data, extras, 658 sync, false, mAppThread.asBinder(), sendingUser); 659 r.info = info; 660 r.compatInfo = compatInfo; 661 queueOrSendMessage(H.RECEIVER, r); 662 } //android.app.ActivityThread.H 2038 private void queueOrSendMessage(int what, Object obj) { 2039 queueOrSendMessage(what, obj, 0, 0); 2040 } 1471 case RECEIVER: 1472 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp"); 1473 handleReceiver((ReceiverData)msg.obj); 1474 maybeSnapshot(); 1475 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1476 break; 2359 private void handleReceiver(ReceiverData data) { 2360 // If we are getting ready to gc after going to the background, well 2361 // we are back active so skip it. 2362 unscheduleGcIdler(); 2363 2364 String component = data.intent.getComponent().getClassName(); 2365 2366 LoadedApk packageInfo = getPackageInfoNoCheck( 2367 data.info.applicationInfo, data.compatInfo); 2368 2369 IActivityManager mgr = ActivityManagerNative.getDefault(); 2370 2371 BroadcastReceiver receiver; 2372 try { 2373 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 2374 data.intent.setExtrasClassLoader(cl); 2375 data.setExtrasClassLoader(cl); 2376 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance(); 2377 } catch (Exception e) { 2378 if (DEBUG_BROADCAST) Slog.i(TAG, 2379 "Finishing failed broadcast to " + data.intent.getComponent()); 2380 data.sendFinished(mgr); 2381 throw new RuntimeException( 2382 "Unable to instantiate receiver " + component 2383 + ": " + e.toString(), e); 2384 } 2385 2386 try { 2387 Application app = packageInfo.makeApplication(false, mInstrumentation); 2388 2389 if (localLOGV) Slog.v( 2390 TAG, "Performing receive of " + data.intent 2391 + ": app=" + app 2392 + ", appName=" + app.getPackageName() 2393 + ", pkg=" + packageInfo.getPackageName() 2394 + ", comp=" + data.intent.getComponent().toShortString() 2395 + ", dir=" + packageInfo.getAppDir()); 2396 2397 ContextImpl context = (ContextImpl)app.getBaseContext(); 2398 sCurrentBroadcastIntent.set(data.intent); 2399 receiver.setPendingResult(data); 2400 receiver.onReceive(context.getReceiverRestrictedContext(), 2401 data.intent); 2402 } catch (Exception e) { 2403 if (DEBUG_BROADCAST) Slog.i(TAG, 2404 "Finishing failed broadcast to " + data.intent.getComponent()); 2405 data.sendFinished(mgr); 2406 if (!mInstrumentation.onException(receiver, e)) { 2407 throw new RuntimeException( 2408 "Unable to start receiver " + component 2409 + ": " + e.toString(), e); 2410 } 2411 } finally { 2412 sCurrentBroadcastIntent.set(null); 2413 } 2414 2415 if (receiver.getPendingResult() != null) { 2416 data.finish(); 2417 } 2418 }
4、出口是receiver.onReceive(
),静态注册的ClassLoader.loadClass().newInstance()创建实例,在主线程回调,到这里基本就完成所有流程。
补: