广播主要分为两部分:广播发送者和广播接收者
广播接收者:分为静态注册和动态注册
静态注册:AndroidManifest中声明,PMS初始化时,通过解析AndroidManifest.xml,就能得到所有静态注册的BroadcastReceiver信息
当广播发送者需要向静态注册的BroadcastReceiver接收者发送信息时,如果接收者所在进程未启动,先启动进程,利用反射创建BroadcastReceiver对象,然后才能处理
动态注册:调用Context的registerReceiver函数注册BroadcastReceiver; 当应用程序不再需要监听广播时,则需要调用unregisterReceiver函数进行反注册
本文主要介绍动态注册的流程
Context#registerReceiver
2517 /**
2518 * Register a BroadcastReceiver to be run in the main activity thread. The
2519 * <var>receiver</var> will be called with any broadcast Intent that
2520 * matches <var>filter</var>, in the main application thread.
(receiver处理广播的地方;filter用于过滤,可以接收哪些广播;默认app主线程处理,注意ANR)
2521 *
2522 * <p>The system may broadcast Intents that are "sticky" -- these stay
2523 * around after the broadcast has finished, to be sent to any later
2524 * registrations. If your IntentFilter matches one of these sticky
2525 * Intents, that Intent will be returned by this function
2526 * <strong>and</strong> sent to your <var>receiver</var> as if it had just
2527 * been broadcast.
2528 *
2529 * <p>There may be multiple sticky Intents that match <var>filter</var>,
2530 * in which case each of these will be sent to <var>receiver</var>. In
2531 * this case, only one of these can be returned directly by the function;
2532 * which of these that is returned is arbitrarily decided by the system.
2533 *
2534 * <p>If you know the Intent your are registering for is sticky, you can
2535 * supply null for your <var>receiver</var>. In this case, no receiver is
2536 * registered -- the function simply returns the sticky Intent that
2537 * matches <var>filter</var>. In the case of multiple matches, the same
2538 * rules as described above apply.
2539 *
2540 * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
2541 *
2542 * <p>As of {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH}, receivers
2543 * registered with this method will correctly respect the
2544 * {@link Intent#setPackage(String)} specified for an Intent being broadcast.
2545 * Prior to that, it would be ignored and delivered to all matching registered
2546 * receivers. Be careful if using this for security.</p>
2547 *
2548 * <p class="note">Note: this method <em>cannot be called from a
2549 * {@link BroadcastReceiver} component;</em> that is, from a BroadcastReceiver
2550 * that is declared in an application's manifest. It is okay, however, to call
2551 * this method from another BroadcastReceiver that has itself been registered
2552 * at run time with {@link #registerReceiver}, since the lifetime of such a
2553 * registered BroadcastReceiver is tied to the object that registered it.</p>
2554 *
2555 * @param receiver The BroadcastReceiver to handle the broadcast.
2556 * @param filter Selects the Intent broadcasts to be received.
2557 *
2558 * @return The first sticky intent found that matches <var>filter</var>,
2559 * or null if there are none.
2560 *
2561 * @see #registerReceiver(BroadcastReceiver, IntentFilter, String, Handler)
2562 * @see #sendBroadcast
2563 * @see #unregisterReceiver
2564 */
2565 @Nullable
2566 public abstract Intent registerReceiver(@Nullable BroadcastReceiver receiver,
2567 IntentFilter filter);
注册一个广播接受者,至少有两个条件;BroadcastReceiver实例(类比ServiceConnection),filter(可接收广播的过滤条件)
ContextImpl#registerReceiver
1445 @Override
1446 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
1447 return registerReceiver(receiver, filter, null, null);
1448 }
1456 @Override
1457 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1458 String broadcastPermission, Handler scheduler) {
//broadcastPermission广播权限,当receiver注册了相应的广播权限后,只有发送方区有同样的权限才能传到相应的receiver中
//scheduler默认是主线程Handler处理onReceive操作,如果指定了相应线程的Handler,onReceive函数由scheduler对应线程处理
1459 return registerReceiverInternal(receiver, getUserId(),
1460 filter, broadcastPermission, scheduler, getOuterContext(), 0);
1461 }
ContextImpl#registerReceiverInternal
1477 private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
1478 IntentFilter filter, String broadcastPermission,
1479 Handler scheduler, Context context, int flags) {
1480 IIntentReceiver rd = null;
1481 if (receiver != null) {
1482 if (mPackageInfo != null && context != null) {
//mPackageInfo的类型为LoadedApk
1483 if (scheduler == null) {
//未设置scheduler时,将使用主线程的handler处理
//这就是默认情况下,Receiver的onReceive函数在主线程被调用的原因
1484 scheduler = mMainThread.getHandler();
1485 }
//getReceiverDispatcher函数的内部,利用BroadcastReceiver构造出ReceiverDispatcher
//返回ReceiverDispatcher中的IIntentReceiver对象
//IIntentReceiver是注册到AMS中,供AMS回调的Binder通信接口
1486 rd = mPackageInfo.getReceiverDispatcher(
1487 receiver, context, scheduler,
1488 mMainThread.getInstrumentation(), true);
1489 } else {
1490 if (scheduler == null) {
1491 scheduler = mMainThread.getHandler();
1492 }
1493 rd = new LoadedApk.ReceiverDispatcher(
1494 receiver, context, scheduler, null, true).getIIntentReceiver();
1495 }
1496 }
1497 try {
1498 final Intent intent = ActivityManager.getService().registerReceiver(
1499 mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
1500 broadcastPermission, userId, flags); //通过AMS来注册广播接收者
1501 if (intent != null) {
1502 intent.setExtrasClassLoader(getClassLoader());
1503 intent.prepareToEnterProcess();
1504 }
1505 return intent;
1506 } catch (RemoteException e) {
1507 throw e.rethrowFromSystemServer();
1508 }
1509 }
LoadedApk#getReceiverDispatcher
类似于LoadedApk#getServiceDispatcher,ServiceDispatcher
124 private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
125 = new ArrayMap<>();
1201 public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
1202 Context context, Handler handler,
1203 Instrumentation instrumentation, boolean registered) {
//在receiver的注册端,保存<BroadcastReceiver实例对象,对应LoadedApk.ReceiverDispatcher>的一张表
1204 synchronized (mReceivers) {
1205 LoadedApk.ReceiverDispatcher rd = null;
1206 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
1207 if (registered) {
1208 map = mReceivers.get(context);
1209 if (map != null) {
1210 rd = map.get(r); //找到缓存中的ReceiverDispatcher对象了
1211 }
1212 }
1213 if (rd == null) {
1214 rd = new ReceiverDispatcher(r, context, handler,
1215 instrumentation, registered); //创建一个
1216 if (registered) {
1217 if (map == null) {
1218 map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
1219 mReceivers.put(context, map); //并保存在缓存中
1220 }
1221 map.put(r, rd);
1222 }
1223 } else {
1224 rd.validate(context, handler); //检查context和handler是否一致
1225 }
1226 rd.mForgotten = false;
1227 return rd.getIIntentReceiver(); //返回InnerReceiver,是一个binder对象,通过它AMS可以远程调用BroadcastReceiver中的onReceive方法
1228 }
1229 }
LoadedApk#ReceiverDispatcher相关结构
29oneway interface IIntentReceiver {
//oneway interface AMS远程调用performReceive时不会阻塞,只是发送事务数据并立即返回
30 void performReceive(in Intent intent, int resultCode, String data,
31 in Bundle extras, boolean ordered, boolean sticky, int sendingUser);
32}
1281 static final class ReceiverDispatcher {
1282
1283 final static class InnerReceiver extends IIntentReceiver.Stub {
1284 final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher; //指向ReceiverDispatcher 外部类的一个弱引用
1285 final LoadedApk.ReceiverDispatcher mStrongRef;
1286 //InnerReceiver实现了IIntentReceiver的binder对象
1287 InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
1288 mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
1289 mStrongRef = strong ? rd : null;
1290 }
1291
1292 @Override
1293 public void performReceive(Intent intent, int resultCode, String data,
1294 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
1295 final LoadedApk.ReceiverDispatcher rd;
1296 if (intent == null) {
1297 Log.wtf(TAG, "Null intent received");
1298 rd = null;
1299 } else {
1300 rd = mDispatcher.get();
1301 }
1302 if (ActivityThread.DEBUG_BROADCAST) {
1303 int seq = intent.getIntExtra("seq", -1);
1304 Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction()
1305 + " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null));
1306 }
1307 if (rd != null) { //指向外部对象的弱引用,先判断是否为null
1308 rd.performReceive(intent, resultCode, data, extras,
1309 ordered, sticky, sendingUser); //调用其外部类的performReceive方法,和bindService客户端的ServiceConnection一样
1310 } else {
//注册的broadcast实例提前被销毁的情况
1311 // The activity manager dispatched a broadcast to a registered
1312 // receiver in this process, but before it could be delivered the
1313 // receiver was unregistered. Acknowledge the broadcast on its
1314 // behalf so that the system's broadcast sequence can continue.
1315 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1316 "Finishing broadcast to unregistered receiver");
1317 IActivityManager mgr = ActivityManager.getService();
1318 try {
1319 if (extras != null) {
1320 extras.setAllowFds(false);
1321 }
1322 mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags()); //通篇了解后再回来看这个函数
1323 } catch (RemoteException e) {
1324 throw e.rethrowFromSystemServer();
1325 }
1326 }
1327 }
1328 }
1329
1330 final IIntentReceiver.Stub mIIntentReceiver; //receiver binder 对象
1331 final BroadcastReceiver mReceiver; //实例
1332 final Context mContext;
1333 final Handler mActivityThread;
1334 final Instrumentation mInstrumentation;
1335 final boolean mRegistered;
1336 final IntentReceiverLeaked mLocation;
1337 RuntimeException mUnregisterLocation;
1338 boolean mForgotten;
1339
1340 final class Args extends BroadcastReceiver.PendingResult {
1341 private Intent mCurIntent;
1342 private final boolean mOrdered;
1343 private boolean mDispatched;
1344 private Throwable mPreviousRunStacktrace; // To investigate b/37809561. STOPSHIP remove.
1345
1346 public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
1347 boolean ordered, boolean sticky, int sendingUser) {
1348 super(resultCode, resultData, resultExtras,
1349 mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered,
1350 sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags());
1351 mCurIntent = intent;
1352 mOrdered = ordered;
1353 }
1354
1355 public final Runnable getRunnable() {
1356 return () -> {
1357 final BroadcastReceiver receiver = mReceiver;
1358 final boolean ordered = mOrdered;
1359
1360 if (ActivityThread.DEBUG_BROADCAST) {
1361 int seq = mCurIntent.getIntExtra("seq", -1);
1362 Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
1363 + " seq=" + seq + " to " + mReceiver);
1364 Slog.i(ActivityThread.TAG, " mRegistered=" + mRegistered
1365 + " mOrderedHint=" + ordered);
1366 }
1367
1368 final IActivityManager mgr = ActivityManager.getService();
1369 final Intent intent = mCurIntent;
1370 if (intent == null) {
1371 Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched
1372 + ": run() previously called at "
1373 + Log.getStackTraceString(mPreviousRunStacktrace));
1374 }
1375
1376 mCurIntent = null;
1377 mDispatched = true;
1378 mPreviousRunStacktrace = new Throwable("Previous stacktrace");
1379 if (receiver == null || intent == null || mForgotten) {
1380 if (mRegistered && ordered) {
1381 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1382 "Finishing null broadcast to " + mReceiver);
1383 sendFinished(mgr);
1384 }
1385 return;
1386 }
1387
1388 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
1389
1391 try {
1392 ClassLoader cl = mReceiver.getClass().getClassLoader();
1393 intent.setExtrasClassLoader(cl);
1394 intent.prepareToEnterProcess();
1395 setExtrasClassLoader(cl);
1396 receiver.setPendingResult(this);
1397 receiver.onReceive(mContext, intent); //调用BroadcastReceiver的onReceive
1398 } catch (Exception e) {
1399 if (mRegistered && ordered) {
1400 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1401 "Finishing failed broadcast to " + mReceiver);
1402 sendFinished(mgr);
1403 }
1404 if (mInstrumentation == null ||
1405 !mInstrumentation.onException(mReceiver, e)) {
1406 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1407 throw new RuntimeException(
1408 "Error receiving broadcast " + intent
1409 + " in " + mReceiver, e);
1410 }
1411 }
1412
1413 if (receiver.getPendingResult() != null) {
1414 finish();
1415 }
1416
1417
1418 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1419 };
1420 }
1421 }
1422
1423 ReceiverDispatcher(BroadcastReceiver receiver, Context context,
1424 Handler activityThread, Instrumentation instrumentation,
1425 boolean registered) {
1426 if (activityThread == null) {
1427 throw new NullPointerException("Handler must not be null");
1428 }
1429
1430 mIIntentReceiver = new InnerReceiver(this, !registered);
1431 mReceiver = receiver;
1432 mContext = context;
1433 mActivityThread = activityThread; //执行onReceive任务的Handler
1434 mInstrumentation = instrumentation;
1435 mRegistered = registered;
1436 mLocation = new IntentReceiverLeaked(null);
1437 mLocation.fillInStackTrace();
1438 }
1439
1440 void validate(Context context, Handler activityThread) {
1441 if (mContext != context) {
1442 throw new IllegalStateException(
1443 "Receiver " + mReceiver +
1444 " registered with differing Context (was " +
1445 mContext + " now " + context + ")");
1446 }
1447 if (mActivityThread != activityThread) {
1448 throw new IllegalStateException(
1449 "Receiver " + mReceiver +
1450 " registered with differing handler (was " +
1451 mActivityThread + " now " + activityThread + ")");
1452 }
1453 }
1454
1455 IntentReceiverLeaked getLocation() {
1456 return mLocation;
1457 }
1458
1459 BroadcastReceiver getIntentReceiver() {
1460 return mReceiver;
1461 }
1462
1463 IIntentReceiver getIIntentReceiver() {
1464 return mIIntentReceiver;
1465 }
1466
1467 void setUnregisterLocation(RuntimeException ex) {
1468 mUnregisterLocation = ex;
1469 }
1470
1471 RuntimeException getUnregisterLocation() {
1472 return mUnregisterLocation;
1473 }
1474
1475 public void performReceive(Intent intent, int resultCode, String data,
1476 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
1477 final Args args = new Args(intent, resultCode, data, extras, ordered,
1478 sticky, sendingUser);
1479 if (intent == null) {
1480 Log.wtf(TAG, "Null intent received");
1481 } else {
1482 if (ActivityThread.DEBUG_BROADCAST) {
1483 int seq = intent.getIntExtra("seq", -1);
1484 Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()
1485 + " seq=" + seq + " to " + mReceiver);
1486 }
1487 }
1488 if (intent == null || !mActivityThread.post(args.getRunnable())) { //Handler.post(Runnable) 相当于sendMessage,入队成功返回true
1489 if (mRegistered && ordered) {
1490 IActivityManager mgr = ActivityManager.getService();
1491 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1492 "Finishing sync broadcast to " + mReceiver);
1493 args.sendFinished(mgr);
1494 }
1495 }
1496 }
1497
1498 }
注意这个实现,将业务接口与通信接口分离开来,BroadcastReceiver作为业务接口,InnerReceiver为通信接口,ReceiverDispatcher管理两者之间的联系
当AMS需要调用BroadcastReceiver实例时,其调用路径是:
InnerReceiver.performReceive
ReceiverDispatcher.performReceive
mActivityThread.post(args.getRunnable())
receiver.onReceive(mContext, intent);
mActivityThread = activityThread; 为执行onReceive任务的Handler,默认为主线程的handler,但可以是其他线程的Handler
非主线程调用onReceive中操作的方式
我们必须要明确,这和上文说的在其他线程的Handler中调用BroadcastReceiver的onReceive方法是两回事,比如静态注册的广播接收者,其onReceive必然执行在主线程;我们在主线程中调用onReceive时,如何将其中可能的耗时操作放到子线程中执行呢?
直接创建子线程会有问题;一旦BroadcastReceiver对象处理完广播,并将返回结果通知给AMS后,AMS就有可能清理掉对应进程。 因此,若在onReceive中创建线程处理问题,那么onReceive函数就可能在线程完成工作前返回,导致AMS提前销毁进程。 此时,线程也会消亡,使得工作并没有有效完成。
这样就用到BroadcastReceiver.PendingResult,见google的官方文档:
State for a result that is pending for a broadcast receiver. Returned by goAsync() while in BroadcastReceiver.onReceive(). This allows you to return from onReceive() without having the broadcast terminate; you must call finish() once you are done with the broadcast. This allows you to process the broadcast off of the main thread of your app.
Note on threading: the state inside of this class is not itself thread-safe, however you can use it from any thread if you properly sure that you do not have races. Typically this means you will hand the entire object to another thread, which will be solely responsible for setting any results and finally calling finish().
示例如下:
private class MyBroadcastReceiver extends BroadcastReceiver {
..................
public void onReceive(final Context context, final Intent intent) {
//得到PendingResult
final PendingResult result = goAsync(); //用来保证receiver端的主线程快速返回
//放到异步线程中执行
AsyncHandler.post(new Runnable() {
@Override
public void run() {
handleIntent(context, intent);//可进行一些耗时操作
result.finish();
}
});
}
}
final class AsyncHandler {
private static final HandlerThread sHandlerThread = new HandlerThread("AsyncHandler");
private static final Handler sHandler;
static {
sHandlerThread.start();
sHandler = new Handler(sHandlerThread.getLooper());
}
public static void post(Runnable r) {
sHandler.post(r);
}
private AsyncHandler() {}
}
首先执行一个goAsync(),返回PendingResult对象,并将mPendingResult置为0
401 * @return Returns a {@link PendingResult} representing the result of
402 * the active broadcast. The BroadcastRecord itself is no longer active;
403 * all data and other interaction must go through {@link PendingResult}
404 * APIs. The {@link PendingResult#finish PendingResult.finish()} method
405 * must be called once processing of the broadcast is done.
406 */
407 public final PendingResult goAsync() {
408 PendingResult res = mPendingResult;
409 mPendingResult = null;
410 return res;
411 }
我们在Args中的getRunnable方法中可以看到如下逻辑
1413 if (receiver.getPendingResult() != null) {
1414 finish();
1415 }
647 public final PendingResult getPendingResult() {
648 return mPendingResult;
649 }
普通情况下,在Args的getRunnable方法中调用receiver.onReceive()之前,会调用
1391 try {
1392 ClassLoader cl = mReceiver.getClass().getClassLoader();
1393 intent.setExtrasClassLoader(cl);
1394 intent.prepareToEnterProcess();
1395 setExtrasClassLoader(cl);
1396 receiver.setPendingResult(this);
1397 receiver.onReceive(mContext, intent); //调用BroadcastReceiver的onReceive
1398 } catch (Exception e) {
1399 if (mRegistered && ordered) {
1400 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1401 "Finishing failed broadcast to " + mReceiver);
1402 sendFinished(mgr);
1403 }
1404 if (mInstrumentation == null ||
1405 !mInstrumentation.onException(mReceiver, e)) {
1406 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1407 throw new RuntimeException(
1408 "Error receiving broadcast " + intent
1409 + " in " + mReceiver, e);
1410 }
1411 }
会将Broadcast实例中的mPendingResult设为Args对象
640 public final void setPendingResult(PendingResult result) {
641 mPendingResult = result;
642 }
这样,在调用完onReceive之后,就会走到 finish();
BroadcastReceiver.PendingResult
202 /**
203 * Finish the broadcast. The current result will be sent and the
204 * next broadcast will proceed.
205 */
206 public final void finish() {
207 if (mType == TYPE_COMPONENT) {
208 final IActivityManager mgr = ActivityManager.getService();
209 if (QueuedWork.hasPendingWork()) {
210 // If this is a broadcast component, we need to make sure any
211 // queued work is complete before telling AM we are done, so
212 // we don't have our process killed before that. We now know
213 // there is pending work; put another piece of work at the end
214 // of the list to finish the broadcast, so we don't block this
215 // thread (which may be the main thread) to have it finished.
216 //
217 // Note that we don't need to use QueuedWork.addFinisher() with the
218 // runnable, since we know the AM is waiting for us until the
219 // executor gets to it.
238 QueuedWork.queue(new Runnable() {
239 @Override public void run() {
240 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
241 "Finishing broadcast after work to component " + mToken);
243 sendFinished(mgr);
254 }
255 }, false);
256 } else {
257 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
258 "Finishing broadcast to component " + mToken);
259 sendFinished(mgr);
260 }
261 } else if (mOrderedHint && mType != TYPE_UNREGISTERED) {
262 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
263 "Finishing broadcast to " + mToken);
264 final IActivityManager mgr = ActivityManager.getService();
265 sendFinished(mgr);
266 }
267 }
276 /** @hide */
277 public void sendFinished(IActivityManager am) {
278 synchronized (this) {
279 if (mFinished) {
280 throw new IllegalStateException("Broadcast already finished");
281 }
282 mFinished = true;
283
284 try {
285 if (mResultExtras != null) {
286 mResultExtras.setAllowFds(false);
287 }
288 if (mOrderedHint) {
289 am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras,
290 mAbortBroadcast, mFlags);
291 } else {
292 // This broadcast was sent to a component; it is not ordered,
293 // but we still need to tell the activity manager we are done.
294 am.finishReceiver(mToken, 0, null, null, false, mFlags);
295 }
296 } catch (RemoteException ex) {
297 }
298 }
299 }
300
调用AMS中的finishReceiver
ActivityManagerService#finishReceiver
22678 public void finishReceiver(IBinder who, int resultCode, String resultData,
22679 Bundle resultExtras, boolean resultAbort, int flags) {
22680 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
22681
22682 // Refuse possible leaked file descriptors
22683 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
22684 throw new IllegalArgumentException("File descriptors passed in Bundle");
22685 }
22686
22687 final long origId = Binder.clearCallingIdentity();
22688 try {
22689 boolean doNext = false;
22690 BroadcastRecord r;
22691
22692 synchronized(this) {
22693 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
22694 ? mFgBroadcastQueue : mBgBroadcastQueue;
22703 r = queue.getMatchingOrderedReceiver(who);
22704 if (r != null) {
22705 doNext = r.queue.finishReceiverLocked(r, resultCode,
22706 resultData, resultExtras, resultAbort, true);
22707 }
22708 if (doNext) {
22709 r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
22710 }
22711 // updateOomAdjLocked() will be done here
22712 trimApplicationsLocked();
22713 }
22714
22715 } finally {
22716 Binder.restoreCallingIdentity(origId);
22717 }
22718 }
用于处理完相应的Broadcast,执行下一个广播
而当我们用了goAsync时,因为BroadcastReceiver实例中的mPendingResult成员变量被置为null,因此不会自动调用finish了,就像上面的例子一样,等到执行完耗时操作后,手动调用finish;
可见,在onReceive函数中执行异步操作,主要目的是避免一些操作阻塞了主线程, 但整个操作仍然需要保证在10s内返回结果,尤其是处理有序广播和静态广播时。 毕竟AMS必须要收到返回结果后,才能向下一个BroadcastReceiver发送广播
得到可以用来binder call BroadcastReceiver实例的IIntentReceiver对象后,将其作为参数传递给AMS;
ActivityManagerService#registerReceiver
21342 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
21343 IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
21344 int flags) {
21345 enforceNotIsolatedCaller("registerReceiver");
21346 ArrayList<Intent> stickyIntents = null;
21347 ProcessRecord callerApp = null;
21348 final boolean visibleToInstantApps
21349 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
21350 int callingUid;
21351 int callingPid;
21352 boolean instantApp;
21353 synchronized(this) {
21354 if (caller != null) {
21355 callerApp = getRecordForAppLocked(caller); //callerApp代表客户端进程
21356 if (callerApp == null) {
21357 throw new SecurityException(
21358 "Unable to find app for caller " + caller
21359 + " (pid=" + Binder.getCallingPid()
21360 + ") when registering receiver " + receiver);
21361 }
21362 if (callerApp.info.uid != SYSTEM_UID &&
21363 !callerApp.pkgList.containsKey(callerPackage) &&
21364 !"android".equals(callerPackage)) {
21365 throw new SecurityException("Given caller package " + callerPackage
21366 + " is not running in process " + callerApp);
21367 }
21368 callingUid = callerApp.info.uid;
21369 callingPid = callerApp.pid;
21370 } else {
21371 callerPackage = null;
21372 callingUid = Binder.getCallingUid();
21373 callingPid = Binder.getCallingPid();
21374 }
21375
21376 instantApp = isInstantApp(callerApp, callerPackage, callingUid);
21377 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
21378 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
21379
21380 Iterator<String> actions = filter.actionsIterator(); //从filter中获取action
21381 if (actions == null) {
21382 ArrayList<String> noAction = new ArrayList<String>(1);
21383 noAction.add(null);
21384 actions = noAction.iterator();
21385 }
21386
21387 // Collect stickies of users
21388 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) }; //UserHandle.getUserId(callingUid) 从uid换算出userId
21389 while (actions.hasNext()) {
21390 String action = actions.next();
21391 for (int id : userIds) {
21392 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id); //action对应的Intent list
21393 if (stickies != null) {
//从mStickyBroadcasts中查看用户的sticky Intent
21394 ArrayList<Intent> intents = stickies.get(action);
21395 if (intents != null) {
21396 if (stickyIntents == null) {
21397 stickyIntents = new ArrayList<Intent>();
21398 }
21399 stickyIntents.addAll(intents); //得到系统保存的所有sticky broadcast对应的Intent
21400 }
21401 }
21402 }
21403 }
21404 }
21405
21406 ArrayList<Intent> allSticky = null;
21407 if (stickyIntents != null) {
21408 final ContentResolver resolver = mContext.getContentResolver();
21409 // Look for any matching sticky broadcasts...
21410 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
21411 Intent intent = stickyIntents.get(i);
21412 // Don't provided intents that aren't available to instant apps.
21413 if (instantApp &&
21414 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
21415 continue;
21416 }
21417 // If intent has scheme "content", it will need to acccess
21418 // provider that needs to lock mProviderMap in ActivityThread
21419 // and also it may need to wait application response, so we
21420 // cannot lock ActivityManagerService here.
21421 if (filter.match(resolver, intent, true, TAG) >= 0) {
//匹配发起的Intent数据是否匹配成功,匹配项共有4项action, type, data, category,任何一项匹配不成功都会失败
21422 if (allSticky == null) {
21423 allSticky = new ArrayList<Intent>();
21424 }
21425 allSticky.add(intent); //找到该次注册的广播接收者所有对应的(可响应的)sticky broadcast (Intent)
21426 }
21427 }
21428 }
21429
21430 // The first sticky in the list is returned directly back to the client.
21431 Intent sticky = allSticky != null ? allSticky.get(0) : null; //返回所有匹配队列中的第一个
21432 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
21433 if (receiver == null) {
//当IIntentReceiver为空,则直接返回第一个sticky Intent
21434 return sticky;
21435 }
21436
21437 synchronized (this) {
21438 if (callerApp != null && (callerApp.thread == null
21439 || callerApp.thread.asBinder() != caller.asBinder())) {
21440 // Original caller already died
//注册receiver进程已经死亡
21441 return null;
21442 }
21443 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
21444 if (rl == null) {
21445 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
21446 userId, receiver);
//receiver:IIntentReceiver的binder对象,AMS可以用来调用caller进程中的broadcastReceiver中的方法
//ReceiverList在AMS中可以代表一个broadcatstReceiver,接收一个或多个broadcast对象
21447 if (rl.app != null) {
21448 final int totalReceiversForApp = rl.app.receivers.size(); //ProcessRecord中保存了receivers对象,代表这个进程中有多少个动态注册的receiver
21449 if (totalReceiversForApp >= MAX_RECEIVERS_ALLOWED_PER_APP) {
//一个进程中注册的receiver不能超过1000
21450 throw new IllegalStateException("Too many receivers, total of "
21451 + totalReceiversForApp + ", registered for pid: "
21452 + rl.pid + ", callerPackage: " + callerPackage);
21453 }
21454 rl.app.receivers.add(rl);
21455 } else {
21456 try {
21457 receiver.asBinder().linkToDeath(rl, 0); //为IIntentReceiver注册死亡回调
21458 } catch (RemoteException e) {
21459 return sticky;
21460 }
21461 rl.linkedToDeath = true;
21462 }
21463 mRegisteredReceivers.put(receiver.asBinder(), rl); //将创建的接收者队列ReceiverList保存在AMS中的mRegisteredReceivers
21464 } else if (rl.uid != callingUid) {
21465 throw new IllegalArgumentException(
21466 "Receiver requested to register for uid " + callingUid
21467 + " was previously registered for uid " + rl.uid
21468 + " callerPackage is " + callerPackage);
21469 } else if (rl.pid != callingPid) {
21470 throw new IllegalArgumentException(
21471 "Receiver requested to register for pid " + callingPid
21472 + " was previously registered for pid " + rl.pid
21473 + " callerPackage is " + callerPackage);
21474 } else if (rl.userId != userId) {
21475 throw new IllegalArgumentException(
21476 "Receiver requested to register for user " + userId
21477 + " was previously registered for user " + rl.userId
21478 + " callerPackage is " + callerPackage);
21479 }
//创建新的BroadcastFilter,用于添加的ReceiverList中
(注册一个广播接收者与两个参数有关,一个是用于处理广播的BroadcastReceiver实例,另一个是filter
BroadcastReceiver在AMS中用ReceiverList表示,BroadcastReceiver+filter用 BroadcastFilter表示)
21480 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
21481 permission, callingUid, userId, instantApp, visibleToInstantApps);
21482 if (rl.containsFilter(filter)) {
21483 Slog.w(TAG, "Receiver with filter " + filter
21484 + " already registered for pid " + rl.pid
21485 + ", callerPackage is " + callerPackage);
21486 } else {
21487 rl.add(bf);
21488 if (!bf.debugCheck()) {
21489 Slog.w(TAG, "==> For Dynamic broadcast");
21490 }
21491 mReceiverResolver.addFilter(bf);
21492 }
21493
21494 // Enqueue broadcasts for all existing stickies that match
21495 // this filter.
//所有匹配该filter的sticky广播执行入队操作
//如果注册的该BroadcastReceiver广播接收者所能响应的filter中没有粘性广播,则allSticky == null
//不为null,说明该BroadcastReceiver有粘性广播待响应,所以注册的流程中也有发送广播的流程,构造广播并加入到广播处理队列
21496 if (allSticky != null) {
21497 ArrayList receivers = new ArrayList();
21498 receivers.add(bf);
21499
21500 final int stickyCount = allSticky.size();
21501 for (int i = 0; i < stickyCount; i++) {
21502 Intent intent = allSticky.get(i);
//当intent为前台广播,则返回mFgBroadcastQueue
//当intent为后台广播,则返回mBgBroadcastQueue
21503 BroadcastQueue queue = broadcastQueueForIntent(intent);
//创建broadcastRecord
21504 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
21505 null, -1, -1, false, null, null, OP_NONE, null, receivers,
21506 null, 0, null, null, false, true, true, -1);
21507 queue.enqueueParallelBroadcastLocked(r); //添加到并行队列中
//调度广播,发送BROADCAST_INTENT_MSG消息,触发处理下一个广播
21508 queue.scheduleBroadcastsLocked();
21509 }
21510 }
21511
21512 return sticky;
21513 }
21514 }