Android廣播發送過程分析

該文章主要分析Android廣播發送的順序app

一、既然分析Broadcast的發送過程,那麼先從sendBroadcast(intent)源碼爲入口。oop

這裏能夠直接看(https://my.oschina.net/winHerson/blog/91150) 該博客。從該博客一路跟下來發現如下代碼。 ActivityManagerService的方法ui

private final int broadcastIntentLocked(ProcessRecord callerApp,
            String callerPackage, Intent intent, String resolvedType,
            IIntentReceiver resultTo, int resultCode, String resultData,
            Bundle map, String requiredPermission,
            boolean ordered, boolean sticky, int callingPid, int callingUid) {
                。。。
            }

該方法作了包括不限於如下事情this

得到當前intent對應的動態和靜態receiver

 List receivers = null; //存放當前廣播對應的全部靜態receiver
 List<BroadcastFilter> registeredReceivers = null; //存放當前廣播對應的全部動態receiver

 //每一個BroadcastRecord 存放當前intent 和對應的動態receiver
 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
                    callerPackage, callingPid, callingUid, requiredPermission,
                    receivers, resultTo, resultCode, resultData, map, ordered,
                    sticky, false);
...
 mParallelBroadcasts.add(r); 存放全部無序發送的廣播

 //每一個BroadcastRecord 存放當前intent 和對應的靜態receiver
 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
                    callerPackage, callingPid, callingUid, requiredPermission,
                    receivers, resultTo, resultCode, resultData, map, ordered,
                    sticky, false);
...
 mOrderedBroadcasts.add(r);存放全部有序發送的廣播

而後觸發spa

scheduleBroadcastsLocked();//進行廣播發送

源碼以下.net

private final void scheduleBroadcastsLocked() {
        if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
                + mBroadcastsScheduled);

        if (mBroadcastsScheduled) {
            return;
        }	

        mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
        mBroadcastsScheduled = true;
}

mBroadcastsScheduled 表示是否已經向全部運行的線程發送了一個類型爲BROADCAST_INTENT_MSG的消息,從如下源碼能夠看出線程

final Handler mHandler = new Handler() {
        //public Handler() {
        //    if (localLOGV) Slog.v(TAG, "Handler started!");
        //}

        public void handleMessage(Message msg) {
            switch (msg.what) {
case BROADCAST_INTENT_MSG: {
                if (DEBUG_BROADCAST) Slog.v(
                        TAG, "Received BROADCAST_INTENT_MSG");
                processNextBroadcast(true);
            } break;
。。。。
}}

而後 processNextBroadcast(true);處理每一個廣播發送到對應receivercode

private final void processNextBroadcast(boolean fromMsg) {
        synchronized(this) {
            BroadcastRecord r;

            if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
                    + mParallelBroadcasts.size() + " broadcasts, "
                    + mOrderedBroadcasts.size() + " ordered broadcasts");

            updateCpuStats();
            
            if (fromMsg) { //(1)這裏爲true
                mBroadcastsScheduled = false;
            }

            // First, deliver any non-serialized broadcasts right away.
            while (mParallelBroadcasts.size() > 0) { //(2) 這裏爲true
,由於上面向mParallelBroadcasts添加了數據
                r = mParallelBroadcasts.remove(0);
                r.dispatchTime = SystemClock.uptimeMillis();
                final int N = r.receivers.size();///(3)這裏的r.receivers.就是上面建立BroadcastRecord對象時候傳入的registeredReceivers
                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
                        + r);
                for (int i=0; i<N; i++) {
                    Object target = r.receivers.get(i);
                    if (DEBUG_BROADCAST)  Slog.v(TAG,
                            "Delivering non-ordered to registered "
                            + target + ": " + r);
                    deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
//執行這行代碼
                }
                addBroadcastToHistoryLocked(r);
                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
                        + r);
            }

            // Now take care of the next serialized one...

            // If we are waiting for a process to come up to handle the next
            // broadcast, then do nothing at this point.  Just in case, we
            // check that the process we're waiting for still exists.
            if (mPendingBroadcast != null) {
                if (DEBUG_BROADCAST_LIGHT) {
                    Slog.v(TAG, "processNextBroadcast: waiting for "
                            + mPendingBroadcast.curApp);
                }

                boolean isDead;
                synchronized (mPidsSelfLocked) {
                    isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
                }
                if (!isDead) {
                    // It's still alive, so keep waiting
                    return;
                } else {
                    Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
                            + " died before responding to broadcast");
                    mPendingBroadcast.state = BroadcastRecord.IDLE;
                    mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
                    mPendingBroadcast = null;
                }
            }

            boolean looped = false;
            
            do {// mOrderedBroadcasts這裏是處理有序隊列的,由於上面沒有傳值,就不分析了
                if (mOrderedBroadcasts.size() == 0) {
                    // No more broadcasts pending, so all done!
                    scheduleAppGcsLocked();
                    if (looped) {
                        // If we had finished the last ordered broadcast, then
                        // make sure all processes have correct oom and sched
                        // adjustments.
                        updateOomAdjLocked();
                    }
                    return;
                }
               。。。。。
        }
}

從以上源碼能夠看出Android是把當前的廣播所有分發給每一個receiver後,纔會開始處理下一條廣播。 至於BroadcastReceiver 是如何具體接受廣播的能夠參考(http://blog.csdn.net/windskier/article/details/7251742)對象

相關文章
相關標籤/搜索