BroadcastReceiver的使用方式基本可以总结为,声明、注册、发送广播、注销。重点需要分析得类和方法有:
- A.BroadcastReceiver
- B.IntentFilter
- C.ContextImpl.registerReceiver
- D.ContextImpl.sendBroadcast
- E.ContextImpl.unregisterReceiver
A.BroadcastReceiver
首先看看其结构,代码大概500行,是一个抽象类。BroadcastReceiver主要就包含一个成员变量PendingResult,而PendingResult也只不过是一堆属性的集合,并提供了set和get方法。目测PendingResult也就只是在进程内ActivityThread中传递和使用一下而已。
B.IntentFilter
一个Parcelable数据,代码大概1500行,里面没有什么特殊逻辑,也是一堆属性集合,主要用来过来广播Intent数据。最要的属性有
ArrayList<
String> mActions, 表明了那些action可以被匹配上。
C.ContextImpl.registerReceiver
1609 @Override
1610 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
1611 return registerReceiver(receiver, filter, null, null);
1612 }复制代码
1614 @Override
1615 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1616 String broadcastPermission, Handler scheduler) {
1617 return registerReceiverInternal(receiver, getUserId(),
1618 filter, broadcastPermission, scheduler, getOuterContext());
1619 }复制代码
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();
1636 }
1637 rd = mPackageInfo.getReceiverDispatcher(
1638 receiver, context, scheduler,
1639 mMainThread.getInstrumentation(), true);
1640 }
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 }复制代码
首先获得了一个IIntentReceiver对象,然后调用AMS的registerReceiver方法,传入了ApplicationThread和IIntentReceiver,以及IntentFilter。重点关注一下IIntentReceiver对象,那是一个oneway接口,估计是说每一个函数都是oneway的,那么函数调用就是在Binder线程中异步执行了。这里可以看出来,应该是ActivityThread中创建的,然后传递到AMS中,AMS可以通过其发送消息给ActivityThread让它接收广播数据。
29oneway interface IIntentReceiver {
30 void performReceive(in Intent intent, int resultCode, String data,
31 in Bundle extras, boolean ordered, boolean sticky, int sendingUser);
32}复制代码
看看IIntentReceiver的构建过程
686 public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
687 Context context, Handler handler,
688 Instrumentation instrumentation, boolean registered) {
689 synchronized (mReceivers) {
690 LoadedApk.ReceiverDispatcher rd = null;
691 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
692 if (registered) {
693 map = mReceivers.get(context);
694 if (map != null) {
695 rd = map.get(r);
696 }
697 }
698 if (rd == null) {
699 rd = new ReceiverDispatcher(r, context, handler,
700 instrumentation, registered);
701 if (registered) {
702 if (map == null) {
703 map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
704 mReceivers.put(context, map);
705 }
706 map.put(r, rd);
707 }
708 } else {
709 rd.validate(context, handler);
710 }
711 rd.mForgotten = false;
712 return rd.getIIntentReceiver();
713 }
714 }复制代码
创建了mReceivers用来存储一堆ReceiverDispatcher,而ReceiverDispatcher又与BroadcastRecevier是一对一的关系。这关系类似BindService时见到的mServices、ServiceDispatcher和IBinder。可以看看ReceiverDispatcher的数据结构
766 static final class ReceiverDispatcher {
767
768 final static class InnerReceiver extends IIntentReceiver.Stub {
769 final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
770 final LoadedApk.ReceiverDispatcher mStrongRef;
771
772 InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
773 mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
774 mStrongRef = strong ? rd : null;
775 }
776 public void performReceive(Intent intent, int resultCode, String data,
777 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
778 LoadedApk.ReceiverDispatcher rd = mDispatcher.get();
784 if (rd != null) {
785 rd.performReceive(intent, resultCode, data, extras,
786 ordered, sticky, sendingUser);
787 } else {
794 IActivityManager mgr = ActivityManagerNative.getDefault();
795 try {
796 if (extras != null) {
797 extras.setAllowFds(false);
798 }
799 mgr.finishReceiver(this, resultCode, data, extras, false);
800 } catch (RemoteException e) {
802 }
803 }
804 }
805 }
806
807 final IIntentReceiver.Stub mIIntentReceiver;
808 final BroadcastReceiver mReceiver;
809 final Context mContext;
810 final Handler mActivityThread;
811 final Instrumentation mInstrumentation;
812 final boolean mRegistered;
813 final IntentReceiverLeaked mLocation;
814 RuntimeException mUnregisterLocation;
815 boolean mForgotten;
816
817 final class Args extends BroadcastReceiver.PendingResult implements Runnable {
818 private Intent mCurIntent;
819 private final boolean mOrdered;
820
821 public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
822 boolean ordered, boolean sticky, int sendingUser) {
823 super(resultCode, resultData, resultExtras,
824 mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED,
825 ordered, sticky, mIIntentReceiver.asBinder(), sendingUser);
826 mCurIntent = intent;
827 mOrdered = ordered;
828 }
829
830 public void run() {
831 final BroadcastReceiver receiver = mReceiver;
832 final boolean ordered = mOrdered;
833
834 if (ActivityThread.DEBUG_BROADCAST) {
835 int seq = mCurIntent.getIntExtra("seq", -1);
840 }
841
842 final IActivityManager mgr = ActivityManagerNative.getDefault();
843 final Intent intent = mCurIntent;
844 mCurIntent = null;
845
846 if (receiver == null || mForgotten) {
847 if (mRegistered && ordered) {
850 sendFinished(mgr);
851 }
852 return;
853 }
856 try {
857 ClassLoader cl = mReceiver.getClass().getClassLoader();
858 intent.setExtrasClassLoader(cl);
859 setExtrasClassLoader(cl);
860 receiver.setPendingResult(this);
861 receiver.onReceive(mContext, intent);
862 } catch (Exception e) {
863 if (mRegistered && ordered) {
866 sendFinished(mgr);
867 }
875 }
876
877 if (receiver.getPendingResult() != null) {
878 finish();
879 }
881 }
882 }
883
884 ReceiverDispatcher(BroadcastReceiver receiver, Context context,
885 Handler activityThread, Instrumentation instrumentation,
886 boolean registered) {
891 mIIntentReceiver = new InnerReceiver(this, !registered);
892 mReceiver = receiver;
893 mContext = context;
894 mActivityThread = activityThread;
895 mInstrumentation = instrumentation;
896 mRegistered = registered;
897 mLocation = new IntentReceiverLeaked(null);
898 mLocation.fillInStackTrace();
899 }
915
916 IntentReceiverLeaked getLocation() {
917 return mLocation;
918 }
919
920 BroadcastReceiver getIntentReceiver() {
921 return mReceiver;
922 }
923
924 IIntentReceiver getIIntentReceiver() {
925 return mIIntentReceiver;
926 }
927
928 void setUnregisterLocation(RuntimeException ex) {
929 mUnregisterLocation = ex;
930 }
931
932 RuntimeException getUnregisterLocation() {
933 return mUnregisterLocation;
934 }
935
936 public void performReceive(Intent intent, int resultCode, String data,
937 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
938 if (ActivityThread.DEBUG_BROADCAST) {
939 int seq = intent.getIntExtra("seq", -1);
942 }
943 Args args = new Args(intent, resultCode, data, extras, ordered,
944 sticky, sendingUser);
945 if (!mActivityThread.post(args)) {
946 if (mRegistered && ordered) {
947 IActivityManager mgr = ActivityManagerNative.getDefault();
950 args.sendFinished(mgr);
951 }
952 }
953 }
954
955 }复制代码
分析可知ReceiveDispatcher不过是一个外观类,真正起到通信作用的是内部的InnerReceiver,即一个IIntentReceiver.Stub类。InnerReceiver传递到AMS中,AMS通过InnerReceiver通信,最终调用ReceiverDispatcher.performReceive函数,而这个函数内部将处理逻辑放到了ActivityThread.getHandler中执行Args,即放到了mH中。
把Args.run中的最关键的代码提出来一下,mReceiver来自外部类ReceiveDispatcher的构造函数中第一个参数。因此可以说,先构造了BroadcastReceiver,然后才将创建了一个ReceiveDispatcher,最后才将ReceiveDispatcher.IIntentFilter和IntentFilter注册到AMS中的,回调的顺序是AMS -> IIntentFilter -> ReceiveDispatcher -> Args -> BroadcastReceiver -> onReceive,基本上可以预见到AMS中IIntentFilter和IntentFilter的结构了。下面的代码看看回调顺序,基本不用分析了。
857 ClassLoader cl = mReceiver.getClass().getClassLoader();
858 intent.setExtrasClassLoader(cl);
859 setExtrasClassLoader(cl);
860 receiver.setPendingResult(this);
861 receiver.onReceive(mContext, intent);复制代码
----------------------------------------------------------------------------------------------------------------------
穿越到AMS中调用registerReceiver,最重要的参数是receiver和filter。
15160 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15161 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15163 int callingUid;
15164 int callingPid;
15165 synchronized(this) {
15166 ProcessRecord callerApp = null;
15191
15192 List allSticky = null;
15195 Iterator actions = filter.actionsIterator();
15196 if (actions != null) {
15197 while (actions.hasNext()) {
15198 String action = (String)actions.next();
15199 allSticky = getStickiesLocked(action, filter, allSticky,
15200 UserHandle.USER_ALL);
15201 allSticky = getStickiesLocked(action, filter, allSticky,
15202 UserHandle.getUserId(callingUid));
15203 }
15204 }
15222 ReceiverList rl
15223 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15251 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15252 permission, callingUid, userId);
15253 rl.add(bf);
15257 mReceiverResolver.addFilter(bf);
15258 // 如果有粘性广播匹配,那么需要发给现在注册的这个Receiver,似乎广播里没数据15258 // 同步返回第一个匹配的粘性广播,异步返回所有粘性广播,后面还需要求证一下!!
15261 if (allSticky != null) {
15262 ArrayList receivers = new ArrayList();
15263 receivers.add(bf);
15264
15265 int N = allSticky.size();
15266 for (int i=0; i<N; i++) {
15267 Intent intent = (Intent)allSticky.get(i);
15268 BroadcastQueue queue = broadcastQueueForIntent(intent);
15269 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15270 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15271 null, null, false, true, true, -1);
15272 queue.enqueueParallelBroadcastLocked(r);
15273 queue.scheduleBroadcastsLocked();
15274 }
15275 }
15276
15277 return sticky;
15278 }
15279 }复制代码
这里感觉比较重要的两个数据结构mRegisteredReceivers和mReceiverResolver,还有一个BroadcastQueue队列。
85 final
HashMap<
IBinder,
ReceiverList>
mRegisteredReceivers =
686 new
HashMap<
IBinder,
ReceiverList>();
广播的分发逻辑主要集中在BroadcastQueue中,里面分为并发广播和顺序广播,还有广播超时处理,广播超时会主动执行下一个广播。
------------------------------------------------------------------------------------------------
先总结一下:
1.注册一个广播在ContextImpl这一侧来说,就是在LoadedApk中维护了一个二级map,
ArrayMap<
Context,
ArrayMap<
BroadcastReceiver,
ReceiverDispatcher>>
mReceivers,首先建立通信关系 AMS.IIntentFilter -> ReceiveDispathcer.IIntentFilter -> BroadcastReceiver.
2.对于AMS端来说,就是简单的将IIntentFilter包装一下变成BroadcastFilter,并插入到列表ReceiverList中,最后列表插入到
mRegisteredReceivers的map中。处理了一下粘性广播。
这里预测一下,后续发送过程就是利用Intent在mRegisteredReceivers查找BroadcastFilter的过程,接收的过程就是利用BroadcastFilter发送消息给接受者的过程。
应该看错了,BroadcastFilter和Intent的映射关系放在了mReceiveResolver中,后面发送广播的时候还要使用的。根据Intent查找出匹配的BroadcastFilter
------------------------------------------------------------------------------------------------
1319 @Override
1320 public void sendBroadcast(Intent intent) {
1321 warnIfCallingFromSystemProcess();
1322 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1323 try {
1324 intent.prepareToLeaveProcess();
1325 ActivityManagerNative.getDefault().broadcastIntent(
1326 mMainThread.getApplicationThread(), intent, resolvedType, null,
1327 Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, false,
1328 getUserId());
1329 } catch (RemoteException e) {
1330 }
1331 }复制代码
穿越到AMS中执行broadcastIntent,分析一下传递过来的几个参数:
第一个:ApplicationThread
第二个:Intent
后面的:基本都是null
15888 public final int broadcastIntent(IApplicationThread caller,
15889 Intent intent, String resolvedType, IIntentReceiver resultTo,
15890 int resultCode, String resultData, Bundle map,
15891 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15893 synchronized(this) {
15894 intent = verifyBroadcastLocked(intent);
15895
15896 final ProcessRecord callerApp = getRecordForAppLocked(caller);
15900 int res = broadcastIntentLocked(callerApp,
15901 callerApp != null ? callerApp.info.packageName : null,
15902 intent, resolvedType, resultTo,
15903 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15904 callingPid, callingUid, userId);
15905 Binder.restoreCallingIdentity(origId);
15906 return res;
15907 }
15908 }复制代码
15422 private final int broadcastIntentLocked(ProcessRecord callerApp,
15423 String callerPackage, Intent intent, String resolvedType,
15424 IIntentReceiver resultTo, int resultCode, String resultData,
15425 Bundle map, String requiredPermission, int appOp,
15426 boolean ordered, boolean sticky, int callingPid, int callingUid,
15427 int userId) {
15428 intent = new Intent(intent);
15509 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15510 intent.getAction());
15705 List receivers = null;
15706 List<BroadcastFilter> registeredReceivers = null;
15707 // Need to resolve the intent to interested receivers...
15708 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15709 == 0) {
15710 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15711 }
15712 if (intent.getComponent() == null) {
15713 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15715 UserManagerService ums = getUserManagerLocked();
15716 for (int i = 0; i < users.length; i++) {
15717 if (ums.hasUserRestriction(
15718 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15719 continue;
15720 }
15721 List<BroadcastFilter> registeredReceiversForUser =
15722 mReceiverResolver.queryIntent(intent,
15723 resolvedType, false, users[i]);
15724 if (registeredReceivers == null) {
15725 registeredReceivers = registeredReceiversForUser;
15726 } else if (registeredReceiversForUser != null) {
15727 registeredReceivers.addAll(registeredReceiversForUser);
15728 }
15729 }
15730 } else {
15731 registeredReceivers = mReceiverResolver.queryIntent(intent,
15732 resolvedType, false, userId);
15733 }
15734 }
15736 final boolean replacePending =
15737 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15742 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15743 if (!ordered && NR > 0) {
15747 final BroadcastQueue queue = broadcastQueueForIntent(intent);
15748 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15749 callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15750 appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15751 ordered, sticky, false, userId);
15754 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15755 if (!replaced) {
15756 queue.enqueueParallelBroadcastLocked(r);
15757 queue.scheduleBroadcastsLocked();
15758 }
15759 registeredReceivers = null;
15760 NR = 0;
15761 }
15762
15763 // Merge into one list.
15764 int ir = 0;
15765 if (receivers != null) {
15772 String skipPackages[] = null;
15773 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15774 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15775 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15783 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15785 }
15801
15802 int NT = receivers != null ? receivers.size() : 0;
15803 int it = 0;
15804 ResolveInfo curt = null;
15805 BroadcastFilter curr = null;
15806 while (it < NT && ir < NR) {
15807 if (curt == null) {
15808 curt = (ResolveInfo)receivers.get(it);
15809 }
15810 if (curr == null) {
15811 curr = registeredReceivers.get(ir);
15812 }
15813 if (curr.getPriority() >= curt.priority) {
15814 // Insert this broadcast record into the final list.
15815 receivers.add(it, curr);
15816 ir++;
15817 curr = null;
15818 it++;
15819 NT++;
15820 } else {
15821 // Skip to the next ResolveInfo in the final list.
15822 it++;
15823 curt = null;
15824 }
15825 }
15826 }
15827 while (ir < NR) {
15828 if (receivers == null) {
15829 receivers = new ArrayList();
15830 }
15831 receivers.add(registeredReceivers.get(ir));
15832 ir++;
15833 }
15834
15835 if ((receivers != null && receivers.size() > 0)
15836 || resultTo != null) {
15837 BroadcastQueue queue = broadcastQueueForIntent(intent);
15838 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15839 callerPackage, callingPid, callingUid, resolvedType,
15840 requiredPermission, appOp, receivers, resultTo, resultCode,
15841 resultData, map, ordered, sticky, false, userId);
15849 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15850 if (!replaced) {
15851 queue.enqueueOrderedBroadcastLocked(r);
15852 queue.scheduleBroadcastsLocked();
15853 }
15854 }
15855
15856 return ActivityManager.BROADCAST_SUCCESS;
15857 }复制代码
先从mReceiveResolver中取出Intent对应的广播接收器List<BroadcastFilter>,接着构建一个BroadcastRecord记录,让其进入全局的BroadcastQueue队列,然后看是并发执行还是串行执行。
执行的过程在BroadcastQueue.processNextBroadcast中,去看看源码就行不是很多就不记录了,这里贴出关键代码:
deliverToRegisteredReceiverLocked ->
performReceiveLocked
423 private static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
424 Intent intent, int resultCode, String data, Bundle extras,
425 boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
426 // Send the intent to the receiver asynchronously using one-way binder calls.
427 if (app != null) {
428 if (app.thread != null) {
431 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
432 data, extras, ordered, sticky, sendingUser, app.repProcState);
433 } else {
436 }
437 } else {
438 receiver.performReceive(intent, resultCode, data, extras, ordered,
439 sticky, sendingUser);
440 }
441 }复制代码
最终都调用了
IIntentReceiver.performReceive,为什么app会为null呢,先不要在乎这点细节吧。
------------------------------------------------------------------------------------------------
直接接收:
936 public void performReceive(Intent intent, int resultCode, String data,
937 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
943 Args args = new Args(intent, resultCode, data, extras, ordered,
944 sticky, sendingUser);
945 if (!mActivityThread.post(args)) {
952 }
953 }复制代码
817 final class Args extends BroadcastReceiver.PendingResult implements Runnable {
818 private Intent mCurIntent;
819 private final boolean mOrdered;
820
821 public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
822 boolean ordered, boolean sticky, int sendingUser) {
826 mCurIntent = intent;
827 mOrdered = ordered;
828 }
829
830 public void run() {
831 final BroadcastReceiver receiver = mReceiver;
832 final boolean ordered = mOrdered;
833
842 final IActivityManager mgr = ActivityManagerNative.getDefault();
843 final Intent intent = mCurIntent;
844 mCurIntent = null;
845
856 try {
857 ClassLoader cl = mReceiver.getClass().getClassLoader();
858 intent.setExtrasClassLoader(cl);
859 setExtrasClassLoader(cl);
860 receiver.setPendingResult(this);
861 receiver.onReceive(mContext, intent);
862 } catch (Exception e) {
875 }
876
877 if (receiver.getPendingResult() != null) {
878 finish();
879 }
881 }
882 }复制代码
859 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
860 int resultCode, String dataStr, Bundle extras, boolean ordered,
861 boolean sticky, int sendingUser, int processState) throws RemoteException {
863 receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
864 sticky, sendingUser);
865 }复制代码
------------------------------------------------------------------------------------------------
Broadcast总结:
1.注册过程: ContextImpl -> LoadedApk -> mReceivers (
HashMap<
IBinder,
ReceiverList>) -> IntentFilter(ReceiveDispatcher + Broadcast) ->
AMS.registerReceiver(iCaller, IntentFilter) ->
mReceiverResolver(intent, List<BroadcastFilter>)
2.发送过程:ContextImpl -> AMS.broadcastIntent ->
mReceiverResolver -> List<BroadcastFilter> -> BroadcastQueue -> BroadcastFilter.performReceive -> IIntentFilter.performReceive -> Args.run -> Broadcast.onReceive(mContext, intent)
这里可以发现,Broadcast的注册和发送都添加了一个些通信代表类,单本质上可以简单任务Broadcast具备单向接收消息的能力。
注册:Broadcast -> LoadedApk的映射表中 -> 注册到AMS的映射表中Map<Intent, List<IIntentFilter>>
发送: Intent -> AMS中找到IIntentFilter -> Broadcast.onReceive
------------------------------------------------------------------------------------------------
后面再思考一下:
1.静态广播何时注册的呢
并不是ActivityThread启动时注册的,而是广播Intent在AMS的BroadcastQueue中处理的时候,动态注册上的,逻辑在函数
processCurBroadcastLocked中。静态广播每次度需要动态构建实例化一个BroadcastReceiver对象,很奇怪。
2.进程没有启动的时候,怎么处理的
BroadcastQueue.
processNextBroadcast(boolean
fromMsg) 中如果进程没有启动,那么最后几行代码会启动进程,在进程启动后AMS的attachApplicationLocked中会将挂起的广播初始化sendPendingBroadcastsLocked,并接收一下。
3.并发广播和顺序广播怎么处理的,BroadcastQueue还没看太清楚
4.粘性广播具体的实现