Android广播发送过程分析

本文深入剖析了Android中广播发送的顺序与机制,从sendBroadcast方法入手,详细解读了ActivityManagerService如何处理广播,包括获取动态和静态receiver,以及如何通过BroadcastRecord对象组织并分发广播,最终触发receiver接收广播的过程。

该文章主要分析Android广播发送的顺序

1、既然分析Broadcast的发送过程,那么先从sendBroadcast(intent)源码为入口。

这里可以直接看(https://my.oschina.net/winHerson/blog/91150) 该博客。从该博客一路跟下来发现以下代码。 ActivityManagerService的方法

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) {
                。。。
            }

该方法做了包括不限于以下事情

 获得当前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);存放所有有序发送的广播

然后触发

scheduleBroadcastsLocked();//进行广播发送

源码如下

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);处理每个广播发送到对应receiver

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)

转载于:https://my.oschina.net/u/3336230/blog/854431

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值