最近在系统开发中遇到某个系统服务接收 android.intent.action.BOOT_COMPLETED 广播被延迟接收的问题。
具体表现为开机后此服务过了20多秒才被启动,导致开机过慢。
在网上找了一下,没有找到比较好的解决办法,因此决定自己跟一下。
首先,找到发送这个广播的代码,位于 android/frameworks/base/services/java/com/android/server/am/ActivityManagerService.java 文件中的 finishBooting() 方法中。
在 broadcastIntentLocked 后面添加 LOG 信息,编译 mmm frameworks/base/services/java ,用adb push 替换掉系统的 /system/framework/services.jar 文件。
开机用adb logcat -v time 查看系统 LOG ,发现开机20几秒后,系统即发出了这个广播。看来问题不是出在发送广播部分,而是在接收广播部分。
通过分析 broadcastIntentLocked ,发现它调用了 scheduleBroadcastsLocked 方法,发送了一个 BROADCAST_INTENT_MSG 消息。
在android/frameworks/base/services/java/com/android/server/am/BroadcastQueue.java 的消息处理函数中,调用了 processNextBroadcast 函数,由此函数处理
所有广播消息,并负责启动接收了相应消息的 app 。打开 BroadcastQueue.java 的调试信息后发现,这个系统服务之所以20多秒后才被启动,是因为还有其它好几个
app 和服务都接收了这个开机广播,这个系统服务被最后处理,所以花费了较长时间。
最后将这个服务接收广播的优先级调为最高(21474837),此服务即可在二十几秒后启动了,开机时间从50秒大大缩短至20几秒。
- <intent-filter android:priority="21474837">
- <action android:name="android.intent.action.BOOT_COMPLETED" />
- </intent-filter>