BroadcastReceiver的使用方式基本可以总结为,声明、注册、发送广播、注销。重点需要分析得类和方法有:
  • A.BroadcastReceiver
  • B.IntentFilter
  • C.ContextImpl.registerReceiver
  • D.ContextImpl.sendBroadcast
  • E.ContextImpl.unregisterReceiver

A.BroadcastReceiver

首先看看其结构,代码大概500行,是一个抽象类。BroadcastReceiver主要就包含一个成员变量PendingResult,而PendingResult也只不过是一堆属性的集合,并提供了set和get方法。目测PendingResult也就只是在进程内ActivityThread中传递和使用一下而已。
androidxref.com/5.0.0_r2/xr…

B.IntentFilter

一个Parcelable数据,代码大概1500行,里面没有什么特殊逻辑,也是一堆属性集合,主要用来过来广播Intent数据。最要的属性有ArrayList<String> mActions, 表明了那些action可以被匹配上。
androidxref.com/5.0.0_r2/xr…

C.ContextImpl.registerReceiver

androidxref.com/5.0.0_r2/xr…
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让它接收广播数据。
androidxref.com/5.0.0_r2/xr…
29oneway interface IIntentReceiver {
30    void performReceive(in Intent intent, int resultCode, String data,
31            in Bundle extras, boolean ordered, boolean sticky, int sendingUser);
32}复制代码

androidxref.com/5.0.0_r2/xr…
看看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。
androidxref.com/5.0.0_r2/xr…
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队列。
androidxref.com/5.0.0_r2/xr…
androidxref.com/5.0.0_r2/xr…
androidxref.com/5.0.0_r2/xr…
androidxref.com/5.0.0_r2/xr…
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
------------------------------------------------------------------------------------------------
androidxref.com/5.0.0_r2/xr…
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
androidxref.com/5.0.0_r2/xr…
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呢,先不要在乎这点细节吧。
------------------------------------------------------------------------------------------------
直接接收:
androidxref.com/5.0.0_r2/xr…
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        }复制代码

androidxref.com/5.0.0_r2/xr…
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.粘性广播具体的实现

Broadcast源码分析相关推荐

  1. spark源码分析之Broadcast

    Broadcast简介&使用 在Spark程序中,经常会遇到算子函数中使用较大的外部变量的场景.由于在算子函数中使用到外部变量时,默认情况下,Spark会将该变量复制多个副本,通过网络传输到t ...

  2. Spark源码分析之七:Task运行(一)

    在Task调度相关的两篇文章<Spark源码分析之五:Task调度(一)>与<Spark源码分析之六:Task调度(二)>中,我们大致了解了Task调度相关的主要逻辑,并且在T ...

  3. wireshark协议解析器 源码分析 封装调用

    源码分析 Wireshark启动时,所有解析器进行初始化和注册.要注册的信息包括协议名称.各个字段的信息.过滤用的关键字.要关联的下层协议与端口(handoff)等.在解析过程,每个解析器负责解析自己 ...

  4. Nmap源码分析(脚本引擎)

    Nmap提供了强大的脚本引擎(NSE),以支持通过Lua编程来扩展Nmap的功能.目前脚本库已经包含300多个常用的Lua脚本,辅助完成Nmap的主机发现.端口扫描.服务侦测.操作系统侦测四个基本功能 ...

  5. Android源码分析-全面理解Context

    前言 Context在android中的作用不言而喻,当我们访问当前应用的资源,启动一个新的activity的时候都需要提供Context,而这个Context到底是什么呢,这个问题好像很好回答又好像 ...

  6. spark 源码分析之十八 -- Spark存储体系剖析

    本篇文章主要剖析BlockManager相关的类以及总结Spark底层存储体系. 总述 先看 BlockManager相关类之间的关系如下: 我们从NettyRpcEnv 开始,做一下简单说明. Ne ...

  7. Wifi模块—源码分析Wifi热点扫描2(Android P)

    一 前言 这次接着讲Wifi工程流程中的Wifi热点扫描过程部分的获取扫描结果的过程,也是Wifi扫描过程的延续,可以先看前面Wifi扫描的分析过程. Wifi模块-源码分析Wifi热点扫描(Andr ...

  8. Wifi模块—源码分析Wifi热点扫描(Android P)

    一 前言 这次接着讲Wifi工程流程中的Wifi热点查找过程,也是Wifi启动的过程延续,Wifi启动过程中会更新Wifi的状态,框架层也有相应广播发出,应用层接收到广播后开始进行热点的扫描.可以先看 ...

  9. android6.0源码分析之Camera2 HAL分析

    1.Camera HAL的初始化 Camera HAL的初始加载是在Native的CameraService初始化流程中的,而CameraService初始化是在Main_mediaServer.cp ...

最新文章

  1. Script:列出数据库中子表上没有对应索引的外键
  2. 2021年春季学期-信号与系统-第三次作业参考答案-第八道题
  3. java数据结构 队列_Java数据结构与算法[原创]——队列
  4. JavasSript实现秒转换为“天时分秒”控件和TDD测试方法应用
  5. 04-程序计数器(PC计数器)
  6. html启动word程序,Word工具栏直接启动外部程序
  7. php 自动分配数据到个人,数据表格自动分配列宽的一种实现方法
  8. CPU的内部架构和工作原理
  9. 利用自定义注解,AOP + redis限制ip访问接口次数
  10. JavaScript短信验证码60秒倒计时插件
  11. CS61A 计算机程序的构造与解释 课程介绍及课程学习总结
  12. 数的三次方根(二分查找)
  13. 如何用ps做手绘矢量插画风格照片效果
  14. liferay mysql_Liferay学习笔记(一)Liferay Portal5.2.3环境的初步搭建
  15. 消防法及相关法律法规(二)
  16. kakfa的维护:Brock停止
  17. vue移动端实现拖拽
  18. 登录用友显示java已被阻止_解决Spring Security 用户帐号已被锁定问题
  19. 元宇宙数字藏品,打造数字经济产业,实现全新业态升级
  20. autocad命令、快捷键

热门文章

  1. 面对不同用户,数据中心如何将服务做到极致
  2. Angular 4 依赖注入教程之一 依赖注入简介
  3. SFB 项目经验-09-用Lync 2013或Skype for Business 2015抢火车票
  4. [Spring MVC] - JSP + Freemarker视图解释器整合(转)
  5. Linux之facl
  6. 用protoc-gen-lua生成PB的lua代码
  7. android自带蓝牙例子详解
  8. Winform/WPF实例中的相互操作
  9. dubbo接口测试_Django测试工具平台之Dubbo接口请求 + 前端
  10. Access把每一天的数据累加_如何设计 QQ、微信等第三方账号登陆 ?以及设计数据库表!...