解决广播队列阻塞问题

本文探讨了如何在Android系统启动时优化特定广播发送,通过在ActivityManagerService中添加紧急广播队列,确保高优先级广播不受其他广播队列影响。
摘要由CSDN通过智能技术生成

一:问题点

  刚开机时,系统进行初始化,有很多广播在排队,一些定制广播发送就比较迟才能收到。基于此,研究如何优化特定广播发送流程。

 二:优化方案

2.1 frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

  系统原始有三个广播队列,前台广播队列、后台广播队列和offload广播队列。在广播初始化的地方,增加一个紧急广播队列

    //final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[3];

    boolean mEnableUrgentQueue =false;

    private static final int FLAG_RECEIVER_URGENT = 0x00000400;
    //Special intent which needs to be handled immediately
    private static final String URGENT_BROADCAST_INTENT = "com.iwt.mmi.request,";//android.provider.Telephony.SMS_DELIVER,
    BroadcastQueue mUrgentBroadcastQueue;
    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[4];

2.2 ActivityManagerService.broadcastQueueForIntent

  在寻找intent对应广播队列的函数里,如果该intent属于紧急广播队列,增加FLAG_RECEIVER_URGENT的flag并返回紧急广播队列

    BroadcastQueue broadcastQueueForIntent(Intent intent) {
        if (isOnOffloadQueue(intent.getFlags())) {
            return mOffloadBroadcastQueue;
        }

        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;

        //add begin
        if(SystemProperties.getBoolean("ro.feature.urgent_broadcast",false) ){
          if(URGENT_BROADCAST_INTENT.contains(intent.getAction()+",")){
            if (DEBUG_BROADCAST_BACKGROUND) {
              Slog.i(TAG_BROADCAST,
                        "Broadcast intent " + intent + " on Urgent queue");
            }
            intent.addFlags(FLAG_RECEIVER_URGENT);
            return mUrgentBroadcastQueue;
          }
        }
        //add end

        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
    }

2.3 ActivityManagerService.ActivityManagerService

 在AMS的构造函数中进行紧急广播队列的初始化

        mUrgentBroadcastQueue = new BroadcastQueue(this, mHandler,
                "Urgent", foreConstants, false);
        mBroadcastQueues[3] = mUrgentBroadcastQueue;

2.4 ActivityManagerService.isPendingBroadcastProcessLocked

  在是否是待处理广播队列函数的判断里,增加紧急广播

    boolean isPendingBroadcastProcessLocked(int pid) {
        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
                || mUrgentBroadcastQueue.isPendingBroadcastProcessLocked(pid) //add
                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
                || mOffloadBroadcastQueue.isPendingBroadcastProcessLocked(pid);
    }

2.5 ActivityManagerService.finishReceiver

  在广播发送流程里,查找下一个待发送广播队列,判断intent是否有FLAG_RECEIVER_URGENT flag,如果有,说明是紧急广播队列,则发送紧急广播队列

    public void finishReceiver(IBinder who, int resultCode, String resultData,
            Bundle resultExtras, boolean resultAbort, int flags) {
        final long origId = Binder.clearCallingIdentity();
        try {
            boolean doNext = false;
            BroadcastRecord r;
            BroadcastQueue queue;

            synchronized(this) {
                if (isOnOffloadQueue(flags)) {
                    queue = mOffloadBroadcastQueue;
                } else {
                    //add begin
                    if(mEnableUrgentQueue
                            && (flags & FLAG_RECEIVER_URGENT) != 0) {
                        queue = mUrgentBroadcastQueue;
                    } else {
                        //The following is Android original code
                        //add end
                        queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
                                ? mFgBroadcastQueue : mBgBroadcastQueue;
                    }
                }

                r = queue.getMatchingOrderedReceiver(who);
                if (r != null) {
                    doNext = r.queue.finishReceiverLocked(r, resultCode,
                        resultData, resultExtras, resultAbort, true);
                }
                if (doNext) {
                    r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
                }
                // updateOomAdjLocked() will be done here
                trimApplicationsLocked(false, OomAdjuster.OOM_ADJ_REASON_FINISH_RECEIVER);
            }

        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

三:小结

当广播队列优先级不高,被系统其他广播队列抢占,导致收不到广播时,可采用此方案。方案的核心思想是在系统原有广播队列的基础上,增加一个优先级最高的广播队列,一旦判定intent对应的广播队列属于该广播队列,则在查找广播队列并发送的函数里,直接返回该广播队列,不会被前台或后台广播队列阻塞。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值