BroadcastQueue#addBroadcastToHistoryLocked
1528 private final void addBroadcastToHistoryLocked(BroadcastRecord original) {
1529 if (original.callingUid < 0) {
1530 // This was from a registerReceiver() call; ignore it.
1531 return;
1532 }
//注意這里為BroadcastRecord的finishTime賦值了
1533 original.finishTime = SystemClock.uptimeMillis();
1534
1535 if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
1536 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
1537 createBroadcastTraceTitle(original, BroadcastRecord.DELIVERY_DELIVERED),
1538 System.identityHashCode(original));
1539 }
1540
1541 // Note sometimes (only for sticky broadcasts?) we reuse BroadcastRecords,
1542 // So don't change the incoming record directly.
1543 final BroadcastRecord historyRecord = original.maybeStripForHistory();
1544
1545 mBroadcastHistory[mHistoryNext] = historyRecord;
1546 mHistoryNext = ringAdvance(mHistoryNext, 1, MAX_BROADCAST_HISTORY);
1547
1548 mBroadcastSummaryHistory[mSummaryHistoryNext] = historyRecord.intent;
1549 mSummaryHistoryEnqueueTime[mSummaryHistoryNext] = historyRecord.enqueueClockTime;
1550 mSummaryHistoryDispatchTime[mSummaryHistoryNext] = historyRecord.dispatchClockTime;
1551 mSummaryHistoryFinishTime[mSummaryHistoryNext] = System.currentTimeMillis();
1552 mSummaryHistoryNext = ringAdvance(mSummaryHistoryNext, 1, MAX_BROADCAST_SUMMARY_HISTORY);
1553 }
這個(gè)方用的調(diào)用處有兩處
對于并行廣播:
843 // First, deliver any non-serialized broadcasts right away.
844 while (mParallelBroadcasts.size() > 0) {
845 r = mParallelBroadcasts.remove(0);
846 r.dispatchTime = SystemClock.uptimeMillis();
847 r.dispatchClockTime = System.currentTimeMillis();
848
849 if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
850 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
851 createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
852 System.identityHashCode(r));
853 Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
854 createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
855 System.identityHashCode(r));
856 }
857
858 final int N = r.receivers.size();
859 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
860 + mQueueName + "] " + r);
861 for (int i=0; i<N; i++) {
862 Object target = r.receivers.get(i);
863 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
864 "Delivering non-ordered on [" + mQueueName + "] to registered "
865 + target + ": " + r);
866 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
867 }
868 addBroadcastToHistoryLocked(r);
869 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
870 + mQueueName + "] " + r);
871 }
對于串行廣播:
910 do {
911 if (mOrderedBroadcasts.size() == 0) {
912 // No more broadcasts pending, so all done!
913 mService.scheduleAppGcsLocked();
914 if (looped) {
915 // If we had finished the last ordered broadcast, then
916 // make sure all processes have correct oom and sched
917 // adjustments.
918 mService.updateOomAdjLocked();
919 }
920 return;
921 }
922 r = mOrderedBroadcasts.get(0);
923 boolean forceReceive = false;
924
925 // Ensure that even if something goes awry with the timeout
926 // detection, we catch "hung" broadcasts here, discard them,
927 // and continue to make progress.
928 //
929 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
930 // receivers don't get executed with timeouts. They're intended for
931 // one time heavy lifting after system upgrades and can take
932 // significant amounts of time.
933 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
934 if (mService.mProcessesReady && r.dispatchTime > 0) {
935 long now = SystemClock.uptimeMillis();
936 if ((numReceivers > 0) &&
937 (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
938 Slog.w(TAG, "Hung broadcast ["
939 + mQueueName + "] discarded after timeout failure:"
940 + " now=" + now
941 + " dispatchTime=" + r.dispatchTime
942 + " startTime=" + r.receiverTime
943 + " intent=" + r.intent
944 + " numReceivers=" + numReceivers
945 + " nextReceiver=" + r.nextReceiver
946 + " state=" + r.state);
947 broadcastTimeoutLocked(false); // forcibly finish this broadcast
948 forceReceive = true;
949 r.state = BroadcastRecord.IDLE;
950 }
951 }
952
953 if (r.state != BroadcastRecord.IDLE) {
954 if (DEBUG_BROADCAST) Slog.d(TAG_BROADCAST,
955 "processNextBroadcast("
956 + mQueueName + ") called when not idle (state="
957 + r.state + ")");
958 return;
959 }
960
961 if (r.receivers == null || r.nextReceiver >= numReceivers
962 || r.resultAbort || forceReceive) {
963 // No more receivers for this broadcast! Send the final
964 // result if requested...
965 if (r.resultTo != null) {
966 try {
967 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
968 "Finishing broadcast [" + mQueueName + "] "
969 + r.intent.getAction() + " app=" + r.callerApp);
970 performReceiveLocked(r.callerApp, r.resultTo,
971 new Intent(r.intent), r.resultCode,
972 r.resultData, r.resultExtras, false, false, r.userId);
973 // Set this to null so that the reference
974 // (local and remote) isn't kept in the mBroadcastHistory.
975 r.resultTo = null;
976 } catch (RemoteException e) {
977 r.resultTo = null;
978 Slog.w(TAG, "Failure ["
979 + mQueueName + "] sending broadcast result of "
980 + r.intent, e);
981
982 }
983 }
984
985 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Cancelling BROADCAST_TIMEOUT_MSG");
986 cancelBroadcastTimeoutLocked();
987
988 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
989 "Finished with ordered broadcast " + r);
990
991 // ... and on to the next...
992 addBroadcastToHistoryLocked(r);
993 if (r.intent.getComponent() == null && r.intent.getPackage() == null
994 && (r.intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
995 // This was an implicit broadcast... let's record it for posterity.
996 mService.addBroadcastStatLocked(r.intent.getAction(), r.callerPackage,
997 r.manifestCount, r.manifestSkipCount, r.finishTime-r.dispatchTime);
998 }
999 mOrderedBroadcasts.remove(0);
1000 r = null;
1001 looped = true;
1002 continue;
1003 }
1004 } while (r == null);
因此解幽,Broadcast的finishTime屬于當(dāng)一個(gè)BroadcastRecord中所有receiver執(zhí)行完成鸳址,或者超時(shí)強(qiáng)制終止時(shí),作為BroadcastRecord的finishTime
BroadcastQueue#skipReceiverLocked
主動(dòng)跳過一個(gè)receiver矮固,觸發(fā)下一次處理流程
389 private void skipReceiverLocked(BroadcastRecord r) {
390 logBroadcastReceiverDiscardLocked(r);
391 finishReceiverLocked(r, r.resultCode, r.resultData,
392 r.resultExtras, r.resultAbort, false);
393 scheduleBroadcastsLocked(); //用于觸發(fā)進(jìn)行nextReceiver的處理
394 }
BroadcastQueue#logBroadcastReceiverDiscardLocked
將BroadcastRecord當(dāng)前receiver放棄了失息,打印event log
1651 final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
1652 final int logIndex = r.nextReceiver - 1;
1653 if (logIndex >= 0 && logIndex < r.receivers.size()) {
1654 Object curReceiver = r.receivers.get(logIndex);
1655 if (curReceiver instanceof BroadcastFilter) {
1656 BroadcastFilter bf = (BroadcastFilter) curReceiver;
1657 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
1658 bf.owningUserId, System.identityHashCode(r),
1659 r.intent.getAction(), logIndex, System.identityHashCode(bf));
1660 } else {
1661 ResolveInfo ri = (ResolveInfo) curReceiver;
1662 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
1663 UserHandle.getUserId(ri.activityInfo.applicationInfo.uid),
1664 System.identityHashCode(r), r.intent.getAction(), logIndex, ri.toString());
1665 }
1666 } else {
1667 if (logIndex < 0) Slog.w(TAG,
1668 "Discarding broadcast before first receiver is invoked: " + r);
1669 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
1670 -1, System.identityHashCode(r),
1671 r.intent.getAction(),
1672 r.nextReceiver,
1673 "NONE");
1674 }
1675 }
BroadcastQueue#finishReceiverLocked
418 public boolean finishReceiverLocked(BroadcastRecord r, int resultCode,
419 String resultData, Bundle resultExtras, boolean resultAbort, boolean waitForServices) {
420 final int state = r.state;
421 final ActivityInfo receiver = r.curReceiver;
422 r.state = BroadcastRecord.IDLE;
423 if (state == BroadcastRecord.IDLE) {
424 Slog.w(TAG, "finishReceiver [" + mQueueName + "] called but state is IDLE");
425 }
426 r.receiver = null;
427 r.intent.setComponent(null);
428 if (r.curApp != null && r.curApp.curReceivers.contains(r)) {
429 r.curApp.curReceivers.remove(r);
430 }
431 if (r.curFilter != null) {
432 r.curFilter.receiverList.curBroadcast = null;
433 }
434 r.curFilter = null;
435 r.curReceiver = null;
436 r.curApp = null;
437 mPendingBroadcast = null;
//置空操作
//將當(dāng)前BroadcastRecord中的一些值置空
438
439 r.resultCode = resultCode;
440 r.resultData = resultData;
441 r.resultExtras = resultExtras;
442 if (resultAbort && (r.intent.getFlags()&Intent.FLAG_RECEIVER_NO_ABORT) == 0) {
443 r.resultAbort = resultAbort;
444 } else {
445 r.resultAbort = false;
446 }
447 //waitForServices的特殊情況
448 if (waitForServices && r.curComponent != null && r.queue.mDelayBehindServices
449 && r.queue.mOrderedBroadcasts.size() > 0
450 && r.queue.mOrderedBroadcasts.get(0) == r) {
451 ActivityInfo nextReceiver;
452 if (r.nextReceiver < r.receivers.size()) {
453 Object obj = r.receivers.get(r.nextReceiver);
454 nextReceiver = (obj instanceof ActivityInfo) ? (ActivityInfo)obj : null;
455 } else {
456 nextReceiver = null;
457 }
458 // Don't do this if the next receive is in the same process as the current one.
459 if (receiver == null || nextReceiver == null
460 || receiver.applicationInfo.uid != nextReceiver.applicationInfo.uid
461 || !receiver.processName.equals(nextReceiver.processName)) {
462 // In this case, we are ready to process the next receiver for the current broadcast,
463 // but are on a queue that would like to wait for services to finish before moving
464 // on. If there are background services currently starting, then we will go into a
465 // special state where we hold off on continuing this broadcast until they are done.
466 if (mService.mServices.hasBackgroundServicesLocked(r.userId)) {
467 Slog.i(TAG, "Delay finish: " + r.curComponent.flattenToShortString());
468 r.state = BroadcastRecord.WAITING_SERVICES; //Broadcast已經(jīng)執(zhí)行完了,要等當(dāng)前user的后臺服務(wù)執(zhí)行完才繼續(xù)下一個(gè)broadcast档址;或者是當(dāng)我們切換用戶時(shí)或者進(jìn)程時(shí)盹兢,我們需要把當(dāng)前用戶的后臺服務(wù)執(zhí)行完,才執(zhí)行下一個(gè)BroadcastRecord或者BroadcastReceiver
469 return false; //返回false守伸,代表暫時(shí)不執(zhí)行下一個(gè)broadcast
470 }
471 }
472 }
473
474 r.curComponent = null;
475
476 // We will process the next receiver right now if this is finishing
477 // an app receiver (which is always asynchronous) or after we have
478 // come back from calling a receiver.
479 return state == BroadcastRecord.APP_RECEIVE
480 || state == BroadcastRecord.CALL_DONE_RECEIVE;
//CALL_DONE_RECEIVE 串行廣播+動(dòng)態(tài)注冊receiver:執(zhí)行完performReceiveLocked后绎秒,將BroadcastRecord的state置為CALL_DONE_RECEIVE
//APP_RECEIVE 串行廣播+靜態(tài)注冊receiver:執(zhí)行processCurBroadcastLocked之前就將狀態(tài)置為APP_RECEIVE
//總之是針對串行廣播的,這個(gè)返回值會(huì)在finishReceiver中被用到尼摹,返回true則自動(dòng)調(diào)用processNextBroadcastLocked见芹,進(jìn)行BroadcastRecord的下一個(gè)receiver的處理
481 }
BroadcastQueue#scheduleBroadcastsLocked
通過BROADCAST_INTENT_MSG消息觸發(fā)下一個(gè)receiver的處理
396 public void scheduleBroadcastsLocked() {
397 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts ["
398 + mQueueName + "]: current="
399 + mBroadcastsScheduled);
400
401 if (mBroadcastsScheduled) {
402 return;
403 }
404 mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
405 mBroadcastsScheduled = true;
406 }
ActivityManagerService#finishReceiver
如調(diào)用BroadcastReceiver實(shí)例的onReceive函數(shù)過程中,如果receiver所在進(jìn)程死了蠢涝;最終會(huì)調(diào)用到
22570 public void finishReceiver(IBinder who, int resultCode, String resultData,
22571 Bundle resultExtras, boolean resultAbort, int flags) {
22572 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
22573
22574 // Refuse possible leaked file descriptors
22575 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
22576 throw new IllegalArgumentException("File descriptors passed in Bundle");
22577 }
22578
22579 final long origId = Binder.clearCallingIdentity();
22580 try {
22581 boolean doNext = false;
22582 BroadcastRecord r;
22583
22584 synchronized(this) {
22585 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
22586 ? mFgBroadcastQueue : mBgBroadcastQueue;
22587 r = queue.getMatchingOrderedReceiver(who);
22588 if (r != null) {
22589 doNext = r.queue.finishReceiverLocked(r, resultCode,
22590 resultData, resultExtras, resultAbort, true); //處理當(dāng)前BroadcastRecord狀態(tài)玄呛,并返回一個(gè)結(jié)果,用于判斷是否要觸發(fā)下一個(gè)processNextBroadcastLocked
22591 }
22592 if (doNext) {
22593 r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
//所以processNextBroadcastLocked中的next不是BroadcastRecord這個(gè)粒度的和二,而是BroadcatReceiver這個(gè)粒度的(針對串行廣播)
//對于并行廣播而言徘铝,每執(zhí)行一次都會(huì)將并行隊(duì)列中的Broadcast全部處理完畢
22594 }
22595 // updateOomAdjLocked() will be done here
22596 trimApplicationsLocked();
22597 }
22598
22599 } finally {
22600 Binder.restoreCallingIdentity(origId);
22601 }
22602 }
超時(shí)發(fā)生ANR的相關(guān)邏輯
每個(gè)receiver都會(huì)嘗試發(fā)送,但是只有mPendingBroadcastTimeoutMessage為false是才會(huì)真正發(fā)送;每次取出BroadcastRecord中的一個(gè)receiver準(zhǔn)備執(zhí)行時(shí)惯吕,就會(huì)先嘗試發(fā)送一個(gè)broadcast的timeout消息
1074 if (! mPendingBroadcastTimeoutMessage) { //mPendingBroadcastTimeoutMessage = true代表當(dāng)前已經(jīng)有BROADCAST_TIMEOUT_MSG消息了惕它,無需再重復(fù)發(fā)送了
1075 long timeoutTime = r.receiverTime + mTimeoutPeriod;
1076 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
1077 "Submitting BROADCAST_TIMEOUT_MSG ["
1078 + mQueueName + "] for " + r + " at " + timeoutTime);
1079 setBroadcastTimeoutLocked(timeoutTime); //針對BroadcastReceiver發(fā)送超時(shí)消息
1080 }
BroadcastQueue#setBroadcastTimeoutLocked
1475 final void setBroadcastTimeoutLocked(long timeoutTime) {
1476 if (! mPendingBroadcastTimeoutMessage) {
1477 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG, this);
1478 mHandler.sendMessageAtTime(msg, timeoutTime);
1479 mPendingBroadcastTimeoutMessage = true;
1480 }
1481 }
那么比如我有4個(gè)receiver,每個(gè)3s废登,那么會(huì)在第四個(gè)的時(shí)候進(jìn)行broadcastTimeoutLocked的處理(如果相關(guān)線程不繁忙的話)
166 final class BroadcastHandler extends Handler {
167 public BroadcastHandler(Looper looper) {
168 super(looper, null, true);
169 }
170
171 @Override
172 public void handleMessage(Message msg) {
173 switch (msg.what) {
174 case BROADCAST_INTENT_MSG: {
175 if (DEBUG_BROADCAST) Slog.v(
176 TAG_BROADCAST, "Received BROADCAST_INTENT_MSG");
177 processNextBroadcast(true);
178 } break;
179 case BROADCAST_TIMEOUT_MSG: {
180 synchronized (mService) {
181 broadcastTimeoutLocked(true);
182 }
183 } break;
184 }
185 }
186 }
BroadcastQueue#broadcastTimeoutLocked
發(fā)生超時(shí)時(shí)淹魄,當(dāng)前BroadcastReceiver所在進(jìn)程ANR
1490 final void broadcastTimeoutLocked(boolean fromMsg) {
1491 if (fromMsg) {
1492 mPendingBroadcastTimeoutMessage = false; //調(diào)到這以后mPendingBroadcastTimeoutMessage 置為false,就可以重新發(fā)送超時(shí)消息了
1493 }
1494
1495 if (mOrderedBroadcasts.size() == 0) {
1496 return;
1497 }
1498
1499 long now = SystemClock.uptimeMillis();
1500 BroadcastRecord r = mOrderedBroadcasts.get(0);
1501 if (fromMsg) {
1502 if (!mService.mProcessesReady) {
1503 // Only process broadcast timeouts if the system is ready. That way
1504 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
1505 // to do heavy lifting for system up.
1506 return;
1507 }
1508
1509 long timeoutTime = r.receiverTime + mTimeoutPeriod;
1510 if (timeoutTime > now) {
1511 // We can observe premature timeouts because we do not cancel and reset the
1512 // broadcast timeout message after each receiver finishes. Instead, we set up
1513 // an initial timeout then kick it down the road a little further as needed
1514 // when it expires.
1515 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
1516 "Premature timeout ["
1517 + mQueueName + "] @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
1518 + timeoutTime);
1519 setBroadcastTimeoutLocked(timeoutTime); //重新發(fā)送BROADCAST_TIMEOUT_MSG消息并直接返回
1520 return;
1521 }
1522 }
1523
1524 BroadcastRecord br = mOrderedBroadcasts.get(0);
1525 if (br.state == BroadcastRecord.WAITING_SERVICES) {
1526 // In this case the broadcast had already finished, but we had decided to wait
1527 // for started services to finish as well before going on. So if we have actually
1528 // waited long enough time timeout the broadcast, let's give up on the whole thing
1529 // and just move on to the next.
1530 Slog.i(TAG, "Waited long enough for: " + (br.curComponent != null
1531 ? br.curComponent.flattenToShortString() : "(null)"));
1532 br.curComponent = null;
1533 br.state = BroadcastRecord.IDLE;
1534 processNextBroadcast(false);
1535 return;
1536 }
1537
//確定超時(shí)了堡距,將r.receiverTime改為當(dāng)前時(shí)間(這樣就不會(huì)因?yàn)檫@個(gè)broadcast超時(shí)影響下一個(gè)receiver所在進(jìn)程也ANR了)甲锡,然后finish當(dāng)前Receiver兆蕉,重新觸發(fā)下一輪流程
1538 // If the receiver app is being debugged we quietly ignore unresponsiveness, just
1539 // tidying up and moving on to the next broadcast without crashing or ANRing this
1540 // app just because it's stopped at a breakpoint.
1541 final boolean debugging = (r.curApp != null && r.curApp.debugging);
1542
1543 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
1544 + ", started " + (now - r.receiverTime) + "ms ago");
1545 r.receiverTime = now;
1546 if (!debugging) {
1547 r.anrCount++;
1548 }
1549
1550 ProcessRecord app = null;
1551 String anrMessage = null;
1552
1553 Object curReceiver;
1554 if (r.nextReceiver > 0) {
1555 curReceiver = r.receivers.get(r.nextReceiver-1);
1556 r.delivery[r.nextReceiver-1] = BroadcastRecord.DELIVERY_TIMEOUT;
1557 } else {
1558 curReceiver = r.curReceiver;
1559 }
1560 Slog.w(TAG, "Receiver during timeout of " + r + " : " + curReceiver);
1561 logBroadcastReceiverDiscardLocked(r);
1562 if (curReceiver != null && curReceiver instanceof BroadcastFilter) {
1563 BroadcastFilter bf = (BroadcastFilter)curReceiver;
1564 if (bf.receiverList.pid != 0
1565 && bf.receiverList.pid != ActivityManagerService.MY_PID) {
1566 synchronized (mService.mPidsSelfLocked) {
1567 app = mService.mPidsSelfLocked.get(
1568 bf.receiverList.pid);
1569 }
1570 }
1571 } else {
1572 app = r.curApp;
1573 }
1574
1575 if (app != null) {
1576 anrMessage = "Broadcast of " + r.intent.toString();
1577 }
1578
1579 if (mPendingBroadcast == r) {
1580 mPendingBroadcast = null;
1581 }
1582
1583 // Move on to the next receiver.
1584 finishReceiverLocked(r, r.resultCode, r.resultData,
1585 r.resultExtras, r.resultAbort, false);
1586 scheduleBroadcastsLocked();
1587
1588 if (!debugging && anrMessage != null) {
1589 // Post the ANR to the handler since we do not want to process ANRs while
1590 // potentially holding our lock.
1591 mHandler.post(new AppNotResponding(app, anrMessage));
1592 }
1593 }
BroadcastQueue#cancelBroadcastTimeoutLocked
只有當(dāng)串行廣播所有的BroadcastReceiver時(shí),或者當(dāng)廣播強(qiáng)制被結(jié)束時(shí)搔体,才會(huì)調(diào)用cancelBroadcastTimeoutLocked恨樟,取消隊(duì)列中BROADCAST_TIMEOUT_MSG消息
1409 final void cancelBroadcastTimeoutLocked() {
1410 if (mPendingBroadcastTimeoutMessage) {
1411 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG, this); //BROADCAST_TIMEOUT_MSG消息從隊(duì)列中移除
1412 mPendingBroadcastTimeoutMessage = false;
1413 }
1414 }
下面舉例說明下,已前臺廣播為例:
1.一個(gè)broadcast有4個(gè)receiver疚俱,分別是3,3,3,3
時(shí)間軸
0 3 6 9 10(耗時(shí)操作消息被取出執(zhí)行執(zhí)行了劝术,此時(shí)dispatch time = 9,9+10 = 19)12 此時(shí)整個(gè)Broadcast執(zhí)行完了,會(huì)cancel超時(shí)小心呆奕;因此整個(gè)并沒有耗時(shí)
2.一個(gè)broadcast有2個(gè)receiver养晋,分別是1,13
0 1 10(耗時(shí)操作消息被取出執(zhí)行執(zhí)行了梁钾,此時(shí)dispatch time = 1,1+10 = 11) 11(此時(shí)超時(shí)了绳泉,receiver所在進(jìn)程發(fā)生ANR),然后進(jìn)入下一輪流程姆泻,進(jìn)入下一個(gè)broadcast
3.一個(gè)broadcast有3個(gè)receiver零酪,分別是1,13拇勃,2
0 1 10(耗時(shí)操作消息被取出執(zhí)行執(zhí)行了四苇,此時(shí)dispatch time = 1,1+10 = 11) 11(此時(shí)超時(shí)了,receiver所在進(jìn)程發(fā)生ANR)方咆,然后進(jìn)入下一輪流程月腋,進(jìn)入下一個(gè)receiver,發(fā)送超時(shí)消息(時(shí)間為11+10 = 21)瓣赂,13(該Broadcast執(zhí)行完成榆骚,取消超時(shí)消息);進(jìn)入下一個(gè)Broadcast
4.一個(gè)broadcast有3個(gè)receiver煌集,分別是5妓肢,等待7s才進(jìn)入下一輪,5苫纤,2
0 5 10 (下一輪timeout = 15) 12(取出開始執(zhí)行) 15(ANR,當(dāng)前receiver執(zhí)行超時(shí)),(下一輪timeout = 25),17(此時(shí)結(jié)束职恳,取消超時(shí)消息,觸發(fā)一個(gè)BroadcastRecord)
總結(jié)
用這種方式能查出兩個(gè)receiver處理之間的耗時(shí)超過timeout就會(huì)ANR(本次receiver處理的相關(guān)Message方面,BROADCAST_INTENT_MSG等待取出時(shí)間+執(zhí)行時(shí)間 >= timeout),且不會(huì)連帶影響下一個(gè)receiver(看起來system_server中的ActivityMananger線程耗時(shí)以及receiver所在進(jìn)程的主線程耗時(shí)色徘,來回binder call耗時(shí)恭金,都可能會(huì)造成相關(guān)receiver廣播超時(shí))
deliverToRegisteredReceiverLocked
處理動(dòng)態(tài)注冊的receiver
首先檢查相關(guān)權(quán)限,然后調(diào)用performReceiveLocked進(jìn)行相關(guān)處理
530 private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
531 BroadcastFilter filter, boolean ordered, int index) {
532 boolean skip = false;
//檢查廣播發(fā)送方是否有BroadcastReceiver指定的權(quán)限
533 if (filter.requiredPermission != null) {
534 int perm = mService.checkComponentPermission(filter.requiredPermission,
535 r.callingPid, r.callingUid, -1, true);
536 if (perm != PackageManager.PERMISSION_GRANTED) {
537 Slog.w(TAG, "Permission Denial: broadcasting "
538 + r.intent.toString()
539 + " from " + r.callerPackage + " (pid="
540 + r.callingPid + ", uid=" + r.callingUid + ")"
541 + " requires " + filter.requiredPermission
542 + " due to registered receiver " + filter);
543 skip = true;
544 } else {
545 final int opCode = AppOpsManager.permissionToOpCode(filter.requiredPermission);
546 if (opCode != AppOpsManager.OP_NONE
547 && mService.mAppOpsService.noteOperation(opCode, r.callingUid,
548 r.callerPackage) != AppOpsManager.MODE_ALLOWED) {
549 Slog.w(TAG, "Appop Denial: broadcasting "
550 + r.intent.toString()
551 + " from " + r.callerPackage + " (pid="
552 + r.callingPid + ", uid=" + r.callingUid + ")"
553 + " requires appop " + AppOpsManager.permissionToOp(
554 filter.requiredPermission)
555 + " due to registered receiver " + filter);
556 skip = true;
557 }
558 }
559 }
560 if (!skip && r.requiredPermissions != null && r.requiredPermissions.length > 0) {
561 for (int i = 0; i < r.requiredPermissions.length; i++) {
562 String requiredPermission = r.requiredPermissions[i];
563 int perm = mService.checkComponentPermission(requiredPermission,
564 filter.receiverList.pid, filter.receiverList.uid, -1, true);
565 if (perm != PackageManager.PERMISSION_GRANTED) {
566 Slog.w(TAG, "Permission Denial: receiving "
567 + r.intent.toString()
568 + " to " + filter.receiverList.app
569 + " (pid=" + filter.receiverList.pid
570 + ", uid=" + filter.receiverList.uid + ")"
571 + " requires " + requiredPermission
572 + " due to sender " + r.callerPackage
573 + " (uid " + r.callingUid + ")");
574 skip = true;
575 break;
576 }
577 int appOp = AppOpsManager.permissionToOpCode(requiredPermission);
578 if (appOp != AppOpsManager.OP_NONE && appOp != r.appOp
//檢查BroadcastReceiver是否有Broadcast要求的權(quán)限
581 && mService.mAppOpsService.checkOperation(appOp,
582 filter.receiverList.uid, filter.packageName)
583 != AppOpsManager.MODE_ALLOWED) {
584 Slog.w(TAG, "Appop Denial: receiving "
585 + r.intent.toString()
586 + " to " + filter.receiverList.app
587 + " (pid=" + filter.receiverList.pid
588 + ", uid=" + filter.receiverList.uid + ")"
589 + " requires appop " + AppOpsManager.permissionToOp(
590 requiredPermission)
591 + " due to sender " + r.callerPackage
592 + " (uid " + r.callingUid + ")");
593 skip = true;
594 break;
595 }
596 }
597 }
598 if (!skip && (r.requiredPermissions == null || r.requiredPermissions.length == 0)) {
599 int perm = mService.checkComponentPermission(null,
600 filter.receiverList.pid, filter.receiverList.uid, -1, true);
601 if (perm != PackageManager.PERMISSION_GRANTED) {
602 Slog.w(TAG, "Permission Denial: security check failed when receiving "
603 + r.intent.toString()
604 + " to " + filter.receiverList.app
605 + " (pid=" + filter.receiverList.pid
606 + ", uid=" + filter.receiverList.uid + ")"
607 + " due to sender " + r.callerPackage
608 + " (uid " + r.callingUid + ")");
609 skip = true;
610 }
611 }
612 if (!skip && r.appOp != AppOpsManager.OP_NONE
613
614 && mService.mAppOpsService.noteOperation(r.appOp,
615 filter.receiverList.uid, filter.packageName)
619 != AppOpsManager.MODE_ALLOWED) {
620 Slog.w(TAG, "Appop Denial: receiving "
621 + r.intent.toString()
622 + " to " + filter.receiverList.app
623 + " (pid=" + filter.receiverList.pid
624 + ", uid=" + filter.receiverList.uid + ")"
625 + " requires appop " + AppOpsManager.opToName(r.appOp)
626 + " due to sender " + r.callerPackage
627 + " (uid " + r.callingUid + ")");
628 skip = true;
629 }
630
636
637 if (!mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
638 r.callingPid, r.resolvedType, filter.receiverList.uid)) {
639 skip = true;
640 }
641
642 if (!skip && (filter.receiverList.app == null || filter.receiverList.app.killed
643 || filter.receiverList.app.crashing)) {
644 Slog.w(TAG, "Skipping deliver [" + mQueueName + "] " + r
645 + " to " + filter.receiverList + ": process gone or crashing");
646 skip = true;
647 }
648
649 // Ensure that broadcasts are only sent to other Instant Apps if they are marked as
650 // visible to Instant Apps.
651 final boolean visibleToInstantApps =
652 (r.intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
653
654 if (!skip && !visibleToInstantApps && filter.instantApp
655 && filter.receiverList.uid != r.callingUid) {
656 Slog.w(TAG, "Instant App Denial: receiving "
657 + r.intent.toString()
658 + " to " + filter.receiverList.app
659 + " (pid=" + filter.receiverList.pid
660 + ", uid=" + filter.receiverList.uid + ")"
661 + " due to sender " + r.callerPackage
662 + " (uid " + r.callingUid + ")"
663 + " not specifying FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS");
664 skip = true;
665 }
666
667 if (!skip && !filter.visibleToInstantApp && r.callerInstantApp
668 && filter.receiverList.uid != r.callingUid) {
669 Slog.w(TAG, "Instant App Denial: receiving "
670 + r.intent.toString()
671 + " to " + filter.receiverList.app
672 + " (pid=" + filter.receiverList.pid
673 + ", uid=" + filter.receiverList.uid + ")"
674 + " requires receiver be visible to instant apps"
675 + " due to sender " + r.callerPackage
676 + " (uid " + r.callingUid + ")");
677 skip = true;
678 }
679
680 if (skip) {
//不滿足發(fā)送條件的話褂策,標(biāo)記一下横腿,結(jié)束發(fā)送
681 r.delivery[index] = BroadcastRecord.DELIVERY_SKIPPED;
682 return;
683 }
684
685 // If permissions need a review before any of the app components can run, we drop
686 // the broadcast and if the calling app is in the foreground and the broadcast is
687 // explicit we launch the review UI passing it a pending intent to send the skipped
688 // broadcast.
//特殊情況颓屑,還需要再次檢查權(quán)限,中斷廣播發(fā)送
//再次滿足發(fā)送條件后耿焊,會(huì)重新進(jìn)入到后續(xù)的發(fā)送流程
689 if (mService.mPermissionReviewRequired) {
690 if (!requestStartTargetPermissionsReviewIfNeededLocked(r, filter.packageName,
691 filter.owningUserId)) {
692 r.delivery[index] = BroadcastRecord.DELIVERY_SKIPPED;
693 return;
694 }
695 }
696
697 r.delivery[index] = BroadcastRecord.DELIVERY_DELIVERED;//可以發(fā)送了揪惦,標(biāo)記一下
698
699 // If this is not being sent as an ordered broadcast, then we
700 // don't want to touch the fields that keep track of the current
701 // state of ordered broadcasts.
702 if (ordered) { //針對串行廣播,保存BroadRecord,BroadcastFilter中的結(jié)構(gòu)罗侯,代表串行廣播走到哪了
703 r.receiver = filter.receiverList.receiver.asBinder();
704 r.curFilter = filter;
705 filter.receiverList.curBroadcast = r;
706 r.state = BroadcastRecord.CALL_IN_RECEIVE; //當(dāng)前Broadcast的狀態(tài)
707 if (filter.receiverList.app != null) {
708 // Bump hosting application to no longer be in background
709 // scheduling class. Note that we can't do that if there
710 // isn't an app... but we can only be in that case for
711 // things that directly call the IActivityManager API, which
712 // are already core system stuff so don't matter for this.
713 r.curApp = filter.receiverList.app;
714 filter.receiverList.app.curReceivers.add(r);
715 mService.updateOomAdjLocked(r.curApp, true);
716 }
717 }
723 try {
724 if (DEBUG_BROADCAST_LIGHT) Slog.i(TAG_BROADCAST,
725 "Delivering to " + filter + " : " + r);
726 if (filter.receiverList.app != null && filter.receiverList.app.inFullBackup) {
//若BroadcastReceiver對應(yīng)的進(jìn)程處于fullBackup狀態(tài)(備份和恢復(fù))器腋,則不發(fā)送廣播
727 // Skip delivery if full backup in progress
728 // If it's an ordered broadcast, we need to continue to the next receiver.
729 if (ordered) {
//有序廣播必須處理完一個(gè),才能處理下一個(gè)钩杰,因此這里主動(dòng)觸發(fā)一下
730 skipReceiverLocked(r);
731 }
732 } else {
//執(zhí)行發(fā)送工作
733 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
734 new Intent(r.intent), r.resultCode, r.resultData,
735 r.resultExtras, r.ordered, r.initialSticky, r.userId);
736 }
737 if (ordered) {
738 r.state = BroadcastRecord.CALL_DONE_RECEIVE; //將BroadcastRecord的state設(shè)為CALL_DONE_RECEIVE
//從字面上理解纫塌,似乎取已經(jīng)通過performReceiveLocked來調(diào)用BroadcastRecord實(shí)例中的onReceive了
739 }
740 } catch (RemoteException e) {
741 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
742 if (ordered) {
743 r.receiver = null;
744 r.curFilter = null;
745 filter.receiverList.curBroadcast = null;
746 if (filter.receiverList.app != null) {
747 filter.receiverList.app.curReceivers.remove(r);
748 }
749 }
750 }
751 }
BroadcastQueue#performReceiveLocked
495 void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
496 Intent intent, int resultCode, String data, Bundle extras,
497 boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
498 // Send the intent to the receiver asynchronously using one-way binder calls.
499 if (app != null) { //app:receiver所在進(jìn)程
500 if (app.thread != null) {
501 // If we have an app thread, do the call through that so it is
502 // correctly ordered with other one-way calls.
503 try {
504 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
505 data, extras, ordered, sticky, sendingUser, app.repProcState);
//app進(jìn)程中的一個(gè)binder線程響應(yīng)(binder call都是binder線程響應(yīng)的),在其中會(huì)調(diào)用mActivityThread.post來發(fā)送消息讲弄,最終調(diào)用onReceive函數(shù)措左;mActivityThread默認(rèn)為null
506 // TODO: Uncomment this when (b/28322359) is fixed and we aren't getting
507 // DeadObjectException when the process isn't actually dead.
508 //} catch (DeadObjectException ex) {
509 // Failed to call into the process. It's dying so just let it die and move on.
510 // throw ex;
511 } catch (RemoteException ex) {
512 // Failed to call into the process. It's either dying or wedged. Kill it gently.
513 synchronized (mService) {
514 Slog.w(TAG, "Can't deliver broadcast to " + app.processName
515 + " (pid " + app.pid + "). Crashing it.");
516 app.scheduleCrash("can't deliver broadcast");
517 }
518 throw ex;
519 }
520 } else {
521 // Application has died. Receiver doesn't exist.
522 throw new RemoteException("app.thread must not be null");
523 }
524 } else {
//如果動(dòng)態(tài)接收者的所在進(jìn)程已死亡,則IIntentReceiver中弱引用的LoadedApk.ReceiverDispatcher為null
//則調(diào)用AMS的finishReceiver
525 receiver.performReceive(intent, resultCode, data, extras, ordered,
526 sticky, sendingUser);
527 }
528 }
BroadcastQueue#processCurBroadcastLocked
處理靜態(tài)廣播(此時(shí)所在進(jìn)程已喚起)
273 private final void processCurBroadcastLocked(BroadcastRecord r,
274 ProcessRecord app, boolean skipOomAdj) throws RemoteException {
275 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
276 "Process cur broadcast " + r + " for app " + app);
277 if (app.thread == null) {
278 throw new RemoteException();
279 }
280 if (app.inFullBackup) {
281 skipReceiverLocked(r);
282 return;
283 }
284
285 r.receiver = app.thread.asBinder();
286 r.curApp = app;
287 app.curReceivers.add(r);
288 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
289 mService.updateLruProcessLocked(app, false, null);
// 要派發(fā)之前避除,調(diào)整這個(gè)進(jìn)程的優(yōu)先級
// 所以app在receiver執(zhí)行的過程中優(yōu)先級是很高的
290 if (!skipOomAdj) {
291 mService.updateOomAdjLocked();
292 }
293
294 // Tell the application to launch this receiver.
295 r.intent.setComponent(r.curComponent);
296
297 boolean started = false;
298 try {
299 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
300 "Delivering to component " + r.curComponent
301 + ": " + r);
302 mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
303 PackageManager.NOTIFY_PACKAGE_USE_BROADCAST_RECEIVER);
// binder call到app進(jìn)程 調(diào)用onReceive
304 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
305 mService.compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
306 r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
307 app.repProcState);
308 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
309 "Process cur broadcast " + r + " DELIVERED for app " + app);
310 started = true;
311 } finally {
312 if (!started) {
313 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
314 "Process cur broadcast " + r + ": NOT STARTED!");
315 r.receiver = null;
316 r.curApp = null;
317 app.curReceivers.remove(r);
318 }
319 }
320 }
ActivityThread#scheduleReceiver
776 public final void scheduleReceiver(Intent intent, ActivityInfo info,
777 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
778 boolean sync, int sendingUser, int processState) {
779 updateProcessState(processState, false);
780 ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
781 sync, false, mAppThread.asBinder(), sendingUser);
782 r.info = info;
783 r.compatInfo = compatInfo;
784 sendMessage(H.RECEIVER, r);
785 }
1660 case RECEIVER:
1661 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
1662 handleReceiver((ReceiverData)msg.obj);
1663 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1664 break;
ActivityThread#handleReceiver
private void handleReceiver(ReceiverData data) {
3334 // If we are getting ready to gc after going to the background, well
3335 // we are back active so skip it.
3336 unscheduleGcIdler();
3337
3338 String component = data.intent.getComponent().getClassName();
3339
3340 LoadedApk packageInfo = getPackageInfoNoCheck(
3341 data.info.applicationInfo, data.compatInfo);
3342
3343 IActivityManager mgr = ActivityManager.getService();
3344
3345 Application app;
3346 BroadcastReceiver receiver;
3347 ContextImpl context;
3348 try {
3349 app = packageInfo.makeApplication(false, mInstrumentation);
3350 context = (ContextImpl) app.getBaseContext();
3351 if (data.info.splitName != null) {
3352 context = (ContextImpl) context.createContextForSplit(data.info.splitName);
3353 }
3354 java.lang.ClassLoader cl = context.getClassLoader();
3355 data.intent.setExtrasClassLoader(cl);
3356 data.intent.prepareToEnterProcess();
3357 data.setExtrasClassLoader(cl);
3358 receiver = packageInfo.getAppFactory()
3359 .instantiateReceiver(cl, data.info.name, data.intent);
//對于靜態(tài)廣播而言怎披,啟動(dòng)進(jìn)程后就調(diào)用scheduleReceiver函數(shù)處理廣播
//BroadcastReceiver的實(shí)例還沒有創(chuàng)建,因此需要在此進(jìn)行反射初始化
3360 } catch (Exception e) {
3361 if (DEBUG_BROADCAST) Slog.i(TAG,
3362 "Finishing failed broadcast to " + data.intent.getComponent());
//靜態(tài)廣播創(chuàng)建出問題瓶摆,需要通知AMS凉逛,調(diào)用AMS的finishReceiver
3363 data.sendFinished(mgr);
3364 throw new RuntimeException(
3365 "Unable to instantiate receiver " + component
3366 + ": " + e.toString(), e);
3367 }
3368
3369 try {
3370 if (localLOGV) Slog.v(
3371 TAG, "Performing receive of " + data.intent
3372 + ": app=" + app
3373 + ", appName=" + app.getPackageName()
3374 + ", pkg=" + packageInfo.getPackageName()
3375 + ", comp=" + data.intent.getComponent().toShortString()
3376 + ", dir=" + packageInfo.getAppDir());
3377
3378 sCurrentBroadcastIntent.set(data.intent);
3379 receiver.setPendingResult(data);
3380 receiver.onReceive(context.getReceiverRestrictedContext(),
3381 data.intent);
3382 } catch (Exception e) {
3383 if (DEBUG_BROADCAST) Slog.i(TAG,
3384 "Finishing failed broadcast to " + data.intent.getComponent());
//靜態(tài)廣播調(diào)用onReceive時(shí)出問題,如所在進(jìn)程已被銷毀赏壹,需要通知AMS鱼炒,調(diào)用AMS的finishReceiver
3385 data.sendFinished(mgr);
3386 if (!mInstrumentation.onException(receiver, e)) {
3387 throw new RuntimeException(
3388 "Unable to start receiver " + component
3389 + ": " + e.toString(), e);
3390 }
3391 } finally {
3392 sCurrentBroadcastIntent.set(null);
3393 }
3394
3395 if (receiver.getPendingResult() != null) {
3396 data.finish();
3397 }
3398 }