Broadcast原始碼分析

afxstarx發表於2018-09-09
       BroadcastReceiver的使用方式基本可以總結為,宣告、註冊、傳送廣播、登出。重點需要分析得類和方法有:
  • A.BroadcastReceiver
  • B.IntentFilter
  • C.ContextImpl.registerReceiver
  • D.ContextImpl.sendBroadcast
  • E.ContextImpl.unregisterReceiver

A.BroadcastReceiver

首先看看其結構,程式碼大概500行,是一個抽象類。BroadcastReceiver主要就包含一個成員變數PendingResult,而PendingResult也只不過是一堆屬性的集合,並提供了set和get方法。目測PendingResult也就只是在程式內ActivityThread中傳遞和使用一下而已。
Broadcast原始碼分析

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佇列。
Broadcast原始碼分析
廣播的分發邏輯主要集中在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.粘性廣播具體的實現


相關文章