我是靠谱客的博主 热心毛豆,最近开发中收集的这篇文章主要介绍BroadcastReceiver的工作原理【转】,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

这里主要跟一下android源码,看看BroadcastReceiver的工作原理。BroadcastReceiver分动态注册和静态注册,静态注册涉及到系统开机时的程序安装过程,这里关于静态注册BroadcastReceiver的过程暂时不理,等写到程序安装会有相应的解说。

 

我们将从普通的Activity.registerReceiver开始:

@Override
public Intent registerReceiver(
BroadcastReceiver receiver, IntentFilter filter) {
return mBase.registerReceiver(receiver, filter);
}
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信息。

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继续:

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
}
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
}
</pre>
</div>
<p>  </p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:true;">//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() &gt; 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&lt;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 &amp;&amp; r.dispatchTime &gt; 0) {
617
long now = SystemClock.uptimeMillis();
618
if ((numReceivers &gt; 0) &amp;&amp;
619
(now &gt; 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 &gt;= 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 &amp;&amp;
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&amp;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 &amp;&amp; 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 &amp;&amp; isSingleton) {
832
info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
833
}
834
r.curReceiver = info.activityInfo;
835
if (DEBUG_MU &amp;&amp; r.callingUid &gt; 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 &amp;&amp; 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()&amp;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)分发广播。

第一个分支: 

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 &amp;&amp; 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 &amp;&amp; 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

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

666
final static class InnerReceiver extends IIntentReceiver.Stub {
667
final WeakReference&lt;LoadedApk.ReceiverDispatcher&gt; mDispatcher;
668
final LoadedApk.ReceiverDispatcher mStrongRef;
669
670
InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
671
mDispatcher = new WeakReference&lt;LoadedApk.ReceiverDispatcher&gt;(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 &amp;&amp; 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 &amp;&amp; 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 &amp;&amp; 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。

 

第二个分支:

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进程

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()创建实例,在主线程回调,到这里基本就完成所有流程。

 

补:

 

 
 

转载于:https://www.cnblogs.com/chenlong-50954265/p/5671188.html

最后

以上就是热心毛豆为你收集整理的BroadcastReceiver的工作原理【转】的全部内容,希望文章能够帮你解决BroadcastReceiver的工作原理【转】所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部