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

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
  1. if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {  
  2.     // Start looking for apps that are abusing wake locks.  
  3.     Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);  
  4.     mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);  
  5.     // Tell anyone interested that we are done booting!  
  6.     SystemProperties.set("sys.boot_completed""1");  
  7.     SystemProperties.set("dev.bootcomplete""1");  
  8.     for (int i=0; i
  9.         UserStartedState uss = mStartedUsers.valueAt(i);  
  10.         if (uss.mState == UserStartedState.STATE_BOOTING) {  
  11.             uss.mState = UserStartedState.STATE_RUNNING;  
  12.             final int userId = mStartedUsers.keyAt(i);  
  13.             Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);  
  14.             intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);  
  15.             intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);  
  16.             broadcastIntentLocked(nullnull, intent, null,  
  17.                     new IIntentReceiver.Stub() {  
  18.                         @Override  
  19.                         public void performReceive(Intent intent, int resultCode,  
  20.                                 String data, Bundle extras, boolean ordered,  
  21.                                 boolean sticky, int sendingUser) {  
  22.                             synchronized (ActivityManagerService.this) {  
  23.                                 requestPssAllProcsLocked(SystemClock.uptimeMillis(),  
  24.                                         truefalse);  
  25.                             }  
  26.                         }  
  27.                     },  
  28.                     0nullnull,  
  29.                     android.Manifest.permission.RECEIVE_BOOT_COMPLETED,  
  30.                     AppOpsManager.OP_NONE, truefalse, MY_PID, Process.SYSTEM_UID,  
  31.                     userId);  
  32.         }  
  33.     }  
  34. }  

在 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
  1. <intent-filter android:priority="2147483647">  
  2.     <action android:name="android.intent.action.BOOT_COMPLETED" />  
  3. intent-filter> 

转载地址:http://blog.csdn.net/cool073/article/details/76151003

你可能感兴趣的:(安卓,BOOT_COMPLETED,安卓自启动,android源码分析)