主页 > 原创 > java.lang.IllegalStateException: Cannot broadcast before boot completed

java.lang.IllegalStateException: Cannot broadcast before boot completed

出现该错误的一个操作时,开机时多次插拔耳机,表现为关机动画重复播放。详细的错误信息为:

02-05 19:13:50.219 V/HeadsetObserver(  170): Headset UEVENT: {SUBSYSTEM=switch, SWITCH_STATE=0, DEVPATH=/devices/virtual/switch/h2w, SEQNUM=1390, ACTION=change, SWITCH_NAME=No Device}
02-05 19:13:50.219 E/ActivityManager(  170): Attempt to launch receivers of broadcast intent Intent { act=android.media.AUDIO_BECOMING_NOISY } before boot completion
02-05 19:13:50.219 W/Vold    (   90): Ignoring unknown switch 'No Device'
02-05 19:13:50.229 E/AndroidRuntime(  170): *** FATAL EXCEPTION IN SYSTEM PROCESS: UEventObserver
02-05 19:13:50.229 E/AndroidRuntime(  170): java.lang.IllegalStateException: Cannot broadcast before boot completed
02-05 19:13:50.229 E/AndroidRuntime(  170):  at com.android.server.am.ActivityManagerService.verifyBroadcastLocked(ActivityManagerService.java:10549)
02-05 19:13:50.229 E/AndroidRuntime(  170):  at com.android.server.am.ActivityManagerService.broadcastIntent(ActivityManagerService.java:10566)
02-05 19:13:50.229 E/AndroidRuntime(  170):  at android.app.ContextImpl.sendBroadcast(ContextImpl.java:663)
02-05 19:13:50.229 E/AndroidRuntime(  170):  at com.android.server.HeadsetObserver.update(HeadsetObserver.java:132)
02-05 19:13:50.229 E/AndroidRuntime(  170):  at com.android.server.HeadsetObserver.onUEvent(HeadsetObserver.java:85)
02-05 19:13:50.229 E/AndroidRuntime(  170):  at android.os.UEventObserver$UEventThread.run(UEventObserver.java:108)

可见是android.media.AUDIO_BECOMING_NOISY的广播出现在boot completed前,并且没有注册FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT的标签,打印出该处信息的代码为am的如下方法:

final Intent verifyBroadcastLocked(Intent intent) {
  // Refuse possible leaked file descriptors
  if (intent != null && intent.hasFileDescriptors() == true) {
    throw new IllegalArgumentException("File descriptors passed in Intent");
  }

 int flags = intent.getFlags();

  if (!mProcessesReady) {
   // if the caller really truly claims to know what they're doing, go
    // ahead and allow the broadcast without launching any receivers
    if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
      intent = new Intent(intent);
      intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
    } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
     Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
         + " before boot completion");
     throw new IllegalStateException("Cannot broadcast before boot completed");
    }
 }

 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   throw new IllegalArgumentException(
       "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
  }

 return intent;
}

评论:9

  1. kangear 回复
    2014 年 5 月 7 日 于 上午 9:35

    第二次遇到这个问题了,十分感谢分享。

  2. andy 回复
    2015 年 8 月 24 日 于 下午 3:21

    最后怎么解决的呢?

    • tianyu 回复
      2015 年 8 月 24 日 于 下午 3:27

      仔细阅读原文,注册FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT

      • czronaldo11 回复
        2015 年 8 月 25 日 于 下午 1:45

        求教一下.我注册FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT的时候会报错.如下———“FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT cannot be resolved or is not a field”,我使用Intent为什么找不到”FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT”呢?

  3. changzheng 回复
    2015 年 8 月 25 日 于 下午 1:57

    我使用4.4版本的android api 为什么在Intent中找不到”FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT”这个属性呢?

      • changzheng 回复
        2015 年 8 月 25 日 于 下午 2:23

        还需要冒昧的问一下,我直接在我本地建一个android.content.Intent包,报这个Intent站过去,会有问题么….我是一个android菜鸟,不太了解隐藏api的调用

        • tianyu 回复
          2015 年 8 月 25 日 于 下午 2:35

          如果你一定要用这个接口,不需要定义包,直接 setFlags(0x04000000) 或者 addFlags(0x04000000)就可以了。但是你要考虑到为什么一个普通的应用会需要调用隐藏的api,这时候应该检查应用设计或实现哪里有问题而不是尝试使用隐藏的api。

          • changzheng
            2015 年 8 月 25 日 于 下午 3:18

            恩 多谢, 我刚才用反射把这个变量读出来了…..,默认值给了一个0x04000000,感觉怪怪的…..

发表评论

邮箱地址不会被公开。 必填项已用*标注