文章目录
简介
芯片:MTK
版本:android8
app名称:test
app包名:com.test
广播注册方法:动态注册
复现方法:
- app test内置到系统中并烧录到设备中,正常接收adb发送的广播;
- android studio run app test到设备,无法接收广播;
- 恢复出厂,或者卸载app test再重启后,正常接收广播。
- adb发送广播指令adb shell am broadcast -n com.test/.Receiver -a com.test --es cmd play
简单总结:一个运行中app,使用动态注册广播接收器,接收不到别人发的广播。
广播Receiver伪代码
动态注册广播接收器
java
//广播接受类:
public class Receiver extends BroadcastReceiver {
}
// 在app启动MainActivity时,会调用
myReceiver = new Receiver();
registerReceiver(myReceiver, new IntentFilter("com.test"));
AndroidManifest.xml中设置exported属性为true
xml
<receiver android:name=".Receiver"
android:exported="true">
</receiver>
分析过程
查看logcat
当收不到广播时,会有如下打印,大致原因是被拦截了,没有正常分发给应用:
text
BroadcastQueue system_process D processNextBroadcastLocked, suppress to start process of staticReceiver for package:com.test
就一行打印,太少了,到sdk中定位BroadcastQueue.java这个类,
找到位置:
frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
其打印是由DEBUG_BROADCAST控制的:

在BroadcastQueue.java文件夹下搜索所有.java的文件,查看哪个文件有DEBUG_BROADCAST,定位到文件
frameworks/base/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java

把上图中的DEBUG_BROADCAST改成true,就可以打开:
java
diff --git a/frameworks/base/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java b/frameworks/base/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
index 858e50b175..5bac0fefaf 100755
--- a/frameworks/base/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
+++ b/frameworks/base/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
@@ -46,7 +46,7 @@ public class ActivityManagerDebugConfig {
public static boolean DEBUG_ANR = false;
public static boolean DEBUG_BACKGROUND_CHECK = DEBUG_ALL || false;
public static boolean DEBUG_BACKUP = DEBUG_ALL || false;
- public static boolean DEBUG_BROADCAST = DEBUG_ALL || false;
+ public static boolean DEBUG_BROADCAST = true;//DEBUG_ALL || false;
public static boolean DEBUG_BROADCAST_BACKGROUND = DEBUG_BROADCAST || false;
public static boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
public static boolean DEBUG_BROADCAST_DEFERRAL = DEBUG_BROADCAST || false;
这样重新编译后,就可以查看到更多的logcat打印。
text
2026-01-05 15:36:20.915 999-4284 ActivityManager system_process V Broadcast: Intent { act=com.test flg=0x400010 cmp=com.test/.Receiver (has extras) } ordered=true userid=-2
2026-01-05 15:36:20.915 999-4284 ActivityManager system_process V Enqueueing broadcast: com.test replacePending=false
2026-01-05 15:36:20.916 999-4284 ActivityManager system_process I Broadcast intent Intent { act=com.test flg=0x400010 cmp=com.test/.Receiver (has extras) } on background queue
2026-01-05 15:36:20.916 999-4284 ActivityManager system_process V Enqueueing ordered broadcast BroadcastRecord{82678d3 u0 com.test}
2026-01-05 15:36:20.916 999-4284 BroadcastQueue system_process V Schedule broadcasts [background]: current=false
2026-01-05 15:36:20.916 999-1052 BroadcastQueue system_process V Received BROADCAST_INTENT_MSG [background]
2026-01-05 15:36:20.916 999-1052 BroadcastQueue system_process V processNextBroadcast [background]: 0 parallel broadcasts; 1 ordered
2026-01-05 15:36:20.916 999-1052 BroadcastDispatcher system_process I Next broadcast from main queue: BroadcastRecord{82678d3 u0 com.test}
2026-01-05 15:36:20.916 999-1052 BroadcastQueue system_process V Processing ordered broadcast [background] BroadcastRecord{82678d3 u0 com.test}
2026-01-05 15:36:20.916 999-1052 BroadcastQueue system_process V Submitting BROADCAST_TIMEOUT_MSG [background] for BroadcastRecord{82678d3 u0 com.test} at 410497
2026-01-05 15:36:20.917 999-1052 BroadcastQueue system_process D processNextBroadcastLocked, suppress to start process of staticReceiver for package:com.test
2026-01-05 15:36:20.917 999-1052 BroadcastQueue system_process V Skipping delivery of ordered [background] BroadcastRecord{82678d3 u0 com.test} for reason described above
2026-01-05 15:36:20.917 999-1052 BroadcastQueue system_process V Schedule broadcasts [background]: current=false
2026-01-05 15:36:20.917 999-1052 BroadcastQueue system_process V Received BROADCAST_INTENT_MSG [background]
2026-01-05 15:36:20.917 999-1052 BroadcastQueue system_process V processNextBroadcast [background]: 0 parallel broadcasts; 1 in flight, 0 ordered
2026-01-05 15:36:20.917 999-1052 BroadcastQueue system_process I Finishing broadcast [background] com.test app=null
2026-01-05 15:36:20.918 999-1052 BroadcastQueue system_process V Cancelling BROADCAST_TIMEOUT_MSG
2026-01-05 15:36:20.918 999-1052 BroadcastQueue system_process V Finished with ordered broadcast BroadcastRecord{82678d3 u0 com.test}
日志时间线分析:
text
15:36:20.915 - 广播入队(后台队列)
15:36:20.916 - 开始处理有序广播
15:36:20.917 - 抑制启动接收器进程
15:36:20.917 - 广播被跳过并完成
原因排查
疑问:内置app到系统中,烧录后,再run相同的app到设备中,为什么就会导致app在运行广播也收不到。
从app的状态排查
可能原因:
- 签名不一致
基本排除,因为是同一个包名,如果签名不一样,是run不进去的。 - 应用处于"stopped state"
基本排除,因为app是运行的,有MainActivity在前台。 - 组件被 disable
排查指令:
bash
adb shell dumpsys package com.test | grep -E "enabled|stopped|versionCode|signatures"
重点关注:
- enabled=true?(组件是否启用)
- stopped=true?(是否被停止)
- signatures 是否和系统一致?
是否有 Error: ... signature mismatch?
输入如下:
text
versionCode=1 minSdk=26 targetSdk=32
signatures=PackageSignatures{6091f09 version:2, signatures:[b4addb29], past signatures:[]}
User 0: ceDataInode=2682 installed=true hidden=false suspended=false distractionFlags=0 stopped=false notLaunched=false enabled=0 instant=false virtual=false
versionCode=1 minSdk=26 targetSdk=32
signatures=PackageSignatures{6091f09 version:2, signatures:[b4addb29], past signatures:[]}
User 0: ceDataInode=2682 installed=true hidden=false suspended=false distractionFlags=0 stopped=false notLaunched=false enabled=0 instant=false virtual=false
注意到里面的enabled=0,怀疑是这个状态导致的:
在 Android 系统中,enabled=0 表示该应用的 所有组件(Activity、Service、BroadcastReceiver 等)都被禁用了,即使代码逻辑正确、注册无误,系统也不会启动它或分发广播给它。
enabled=0的原因:
系统策略限制(如 priv-app 权限丢失)
如果原 APK 在 /system/priv-app,拥有 signature|privileged 权限。
调试版安装到 /data/app,失去特权,某些系统服务可能主动 disable 它(较少见,但可能)。
临时启用(用于快速验证是否是 enabled 问题)
bash
adb shell pm enable com.test
执行后再次检查:
```bash
adb shell dumpsys package com.test | grep enabled
如果变成 enabled=1,再发送广播测试是否能收到。
测试结果是收不到,所以不是这个导致的。说明问题不在"组件被禁用",而是更深层的原因。
其它方面排查
接收不到的可能原因:
- 只用了 动态注册 → 应用没启动就没人监听。
- 如果发送的是 隐式广播(没指定包名),Android 8.0+ 会直接丢弃,不唤醒应用。
- 即使是静态注册,若未设置 android:exported="true",外部也无法发送广播给它。
第1,与3都排除,因为代码中使用的是动态册且app已经运行起来了,而且也设置了exported。
测试过程中发现:
使用这条显式指定完整 ComponentName指令发广播,收不到:
bash
adb shell am broadcast -n com.test/.Receiver -a com.test --es cmd play
使用这条指定包名的方式能收到:
bash
adb shell am broadcast -p com.test -a com.test --es cmd play
真相是MTK的快霸(DuraSpeed)搞的鬼
后面在MTK中设置中发现了快霸(DuraSpeed)这个东西,

这个功能是联发科(MTK)为旗下搭载Android系统的设备开发的一套后台进程管理机制,其主要目的是通过限制非关键后台应用的活跃度,来确保前台应用能获得更多系统资源,从而提升手机长期使用后的流畅度。
把这个功能关掉,就正常了。
Android Framework专栏链接
Android专栏
作者:帅得不敢出门