您的位置:首页 > 移动开发 > Android开发

android.intent.action.BOOT_COMPLETED 被延迟接收问题

2017-10-26 18:05 483 查看

android.intent.action.BOOT_COMPLETED 被延迟接收问题

最近在系统开发中遇到某个系统服务接收
android.intent.action.BOOT_COMPLETED
广播被延迟接收的问题。

具体表现为开机后此服务过了20多秒才被启动,导致开机过慢。

在网上找了一下,没有找到比较好的解决办法,因此决定自己跟一下。

首先,找到发送这个广播的代码,位于 android/frameworks/base/services/java/com/android/server/am/ActivityManagerService.java 文件中的 finishBooting() 方法中。

[java]
view plain
copy

if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {  
    // Start looking for apps that are abusing wake locks.  
    Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);  
    mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);  
    // Tell anyone interested that we are done booting!  
    SystemProperties.set("sys.boot_completed", "1");  
    SystemProperties.set("dev.bootcomplete", "1");  
    for (int i=0; i<mStartedUsers.size(); i++) {  
        UserStartedState uss = mStartedUsers.valueAt(i);  
        if (uss.mState == UserStartedState.STATE_BOOTING) {  
            uss.mState = UserStartedState.STATE_RUNNING;  
            final int userId = mStartedUsers.keyAt(i);  
            Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);  
            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);  
            intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);  
            broadcastIntentLocked(null, null, intent, null,  
                    new IIntentReceiver.Stub() {  
                        @Override  
                        public void performReceive(Intent intent, int resultCode,  
                                String data, Bundle extras, boolean ordered,  
                                boolean sticky, int sendingUser) {  
                            synchronized (ActivityManagerService.this) {  
                                requestPssAllProcsLocked(SystemClock.uptimeMillis(),  
                                        true, false);  
                            }  
                        }  
                    },  
                    0, null, null,  
                    android.Manifest.permission.RECEIVE_BOOT_COMPLETED,  
                    AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,  
                    userId);  
        }  
    }  
}  

在 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 和服务都接收了这个开机广播,这个系统服务被最后处理,所以花费了较长时间。

最后将这个服务接收广播的优先级调为最高(2147483647),此服务即可在二十几秒后启动了,开机时间从50秒大大缩短至20几秒。

[html]
view plain
copy

<intent-filter android:priority="2147483647">  
    <action android:name="android.intent.action.BOOT_COMPLETED" />  
</intent-filter> 

转载地址:http://blog.csdn.net/cool073/article/details/76151003
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐