Broadcast(二)registerReceiver时sticky广播

ActivityManagerService.java

registerReceiver最后一段是这个

if (allSticky != null) {
    ArrayList receivers = new ArrayList();
    receivers.add(bf);

    final int stickyCount = allSticky.size();
    for (int i = 0; i < stickyCount; i++) {
        Intent intent = allSticky.get(i);
        BroadcastQueue queue = broadcastQueueForIntent(intent);
        BroadcastRecord r = new BroadcastRecord(queue, intent, null, null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers, null, 0, null, null, false, true, true, -1);
        queue.enqueueParallelBroadcastLocked(r);
        queue.scheduleBroadcastsLocked();
    }
}

// 发送广播的时候intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND),
// 就可以把广播放到mFgBroadcastQueue
// 前后台广播主要是超时时间不一样,见[Broadcast (四)有序广播]
BroadcastQueue broadcastQueueForIntent(Intent intent) {
    final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
    if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
            "Broadcast intent " + intent + " on "
            + (isFg ? "foreground" : "background") + " queue");
    return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
}

BroadcastQueue.java

//无序广播队列
final ArrayList mParallelBroadcasts = new ArrayList<>();

//有序广播队列
final ArrayList mOrderedBroadcasts = new ArrayList<>();

public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
    mParallelBroadcasts.add(r);
    r.enqueueClockTime = System.currentTimeMillis();
}

public void scheduleBroadcastsLocked() {
    ...
    // 有很多地方都是这种形式,服务端收到通知,通过Handler异步处理,
    // 不至于让客户端挂起太久,服务端处理完毕再发个通知到客户端
    // (这时客户端服务端角色就转换了,也就说app和system进程两边经常都是接到通知后就扔给Handler)
    mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
}

private final class BroadcastHandler extends Handler {
    public BroadcastHandler(Looper looper) {
        super(looper, null, true);
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case BROADCAST_INTENT_MSG: {
                processNextBroadcast(true);
            } break;
            ...
        }
    }
}

final void processNextBroadcast(boolean fromMsg) {
    //全程保持AMS锁,其他线程(app进程binder通信)都需要等待此方法处理完毕
    synchronized(mService) {
        //step1:处理全部无序广播,遍历动态注册的接收者并通知
        //step2:获取第一条有序广播
        //step3:获取第一个接收者,校验接收者权限
        //step4:设置超时时间,通知接收者
    }
}

registerReceiver的时候只用到了step1
如果有静态注册的接收者,有序广播也会有数据
step234每次只会处理一条广播一个接收者,app onReceive处理完毕会通知system进程,会再次调用processNextBroadcast
其他step在后续sendBroadcast文章分析
processNextBroadcast→step1

        // First, deliver any non-serialized broadcasts right away.
        while (mParallelBroadcasts.size() > 0) {
            r = mParallelBroadcasts.remove(0);
            r.dispatchTime = SystemClock.uptimeMillis();
            r.dispatchClockTime = System.currentTimeMillis();
            final int N = r.receivers.size();
            for (int i=0; i

一直到结束,并没有设置超时,所以registerReceiver时sticky广播调用onReceive并不会导致ANR(普通广播即sendBroadcast和sendStickyBroadcast的动态注册接收者也只是经过processNextBroadcast→step1)

Broadcast(二)registerReceiver时sticky广播_第1张图片

你可能感兴趣的:(Broadcast(二)registerReceiver时sticky广播)