Android 高版本广播延迟问题-新的广播队列实现BroadcastQueueModernImpl

最近在开发安卓14的系统,系统是system和vendor分开的,system是U版本,vendor是S版本,发现通过系统应用发送出来的广播发给应用有500ms的延迟,如下图所示

发送时间是16:03:52.148

接收时间是16:03:52.652 中间有500ms延迟,不可以接受

正常来说如果是无序广播不应该有这么大的时间差才对,研究系统源码发现在AMS将广播加入队列时,高版本对这块做了改动,在发送广播时调用broadcastQueueForIntent获取广播队列,broadcastQueueForIntent使用mEnableModernQueue标志位对前台、后台做了区分,通过mEnableModernQueue这个代码的作用可以看到这个标志位启用了一条新的队列实现

        if (mEnableModernQueue) {
            mBroadcastQueues = new BroadcastQueue[1];
            mBroadcastQueues[0] = new BroadcastQueueModernImpl(this, mHandler,
                    foreConstants, backConstants);
        } else {
            mBroadcastQueues = new BroadcastQueue[4];
            mBroadcastQueues[BROADCAST_QUEUE_FG] = new BroadcastQueueImpl(this, mHandler,
                    "foreground", foreConstants, false, ProcessList.SCHED_GROUP_DEFAULT);
            mBroadcastQueues[BROADCAST_QUEUE_BG] = new BroadcastQueueImpl(this, mHandler,
                    "background", backConstants, true, ProcessList.SCHED_GROUP_BACKGROUND);
            mBroadcastQueues[BROADCAST_QUEUE_BG_OFFLOAD] = new BroadcastQueueImpl(this, mHandler,
                    "offload_bg", offloadConstants, true, ProcessList.SCHED_GROUP_BACKGROUND);
            mBroadcastQueues[BROADCAST_QUEUE_FG_OFFLOAD] = new BroadcastQueueImpl(this, mHandler,
                    "offload_fg", foreConstants, true, ProcessList.SCHED_GROUP_BACKGROUND);
        }

怀疑是这个导致队列的处理优先级造成的问题

解决方法,将AMS里面的mEnableModernQueue这个标志位置成false,

        //mEnableModernQueue = foreConstants.MODERN_QUEUE_ENABLED;
        mEnableModernQueue = false;

重新编译后发现延迟问题得到解决。

原因分析,新的广播队列实现对广播进行了分类,紧急、负载、普通分别有一个队列,等待调度的广播分别维护了紧急、普通、负载三个有序集合,优先级为紧急(3) > 普通(10) > 负载,但是当优先级高的集合被处理的广播数量超过一定限制时,优先级低的广播也有机会得到执行。


每个队列都有一个在未来特定时间“可运行”(runnable at 时间戳)的概念,它支持在每个进程的基础上任意暂停或延迟交付。当它下一次符合执行条件时,该值会受到各种策略的影响,例如:

        ->哪些广播正在等待发送给给定进程。 例如,“紧急”(前台、源于用户交互、闹钟)广播通常会导致较早的runnable at(-120s)时间,或者“延迟”广播通常会导致较晚的runnable at时间
       ->进程或 UID 的当前状态。 例如,“cached”(procState > PROCESS_STATE_RECEIVER)进程通常会导致较晚的runnable at(+120s)时间,或者“instrumented”进程通常会导致较早的runnable at(-120s)时间。

通过命令可以查看广播状态

adb shell dumpsys activity broadcasts

可以看到bcast_delay_normal_millis=+500ms 这里确实对普通广播进行了延迟500毫秒,可以跟实际现象对应上


...
    bcast_delay_normal_millis=+500ms 
    bcast_delay_cached_millis=+2m0s0ms 
    bcast_delay_urgent_millis=-2m0s0ms 
    bcast_delay_foreground_proc_millis=-2m0s0ms 
    bcast_delay_persistent_proc_millis=-2m0s0ms 
...

关于新版广播队列可以参考这个文章android U广播详解(一)_android 如何dump广播-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值