在 BroadcastReceiver 中启动服务时出错

Error when starting a service in BroadcastReceiver

当应用程序关闭或在后台运行时,我尝试从接收器启动服务时遇到此错误。

但文档明确指出:

The state of your BroadcastReceiver (whether it is running or not) affects the state of its containing process, which can in turn affect its likelihood of being killed by the system. For example, when a process executes a receiver (that is, currently running the code in its onReceive() method), it is considered to be a foreground process. The system keeps the process running except under cases of extreme memory pressure.

换句话说,当应用程序在前台时,理论上它可以启动服务。

那么这里的问题是什么?

@Override
public void onReceive(Context context, Intent intent) {
    // assumes WordService is a registered service


    context.startService(new Intent(context, HelloService.class));

}

错误:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.testapp, PID: 26026
    java.lang.RuntimeException: Unable to start receiver com.example.testapp.MyReceiver: java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.example.testapp/.HelloService }: app is in background uid UidRecord{bee03a7 u0a82 RCVR bg:+1m19s133ms idle change:uncached procs:1 seq(0,0,0)}
        at android.app.ActivityThread.handleReceiver(ActivityThread.java:3194)
        at android.app.ActivityThread.-wrap17(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1672)
        at android.os.Handler.dispatchMessage(Handler.java:106)

与您的情况更相关的文档是 in the Android 8.0 release notes

The system distinguishes between foreground and background apps. (The definition of background for purposes of service limitations is distinct from the definition used by memory management; an app might be in the background as pertains to memory management, but in the foreground as pertains to its ability to launch services.) An app is considered to be in the foreground if any of the following is true:

  • It has a visible activity, whether the activity is started or paused.
  • It has a foreground service.
  • Another foreground app is connected to the app, either by binding to one of its services or by making use of one of its content providers. For example, the app is in the foreground if another app binds to its:
    • IME
    • Wallpaper service
    • Notification listener
    • Voice or text service

If none of those conditions is true, the app is considered to be in the background.

(强调)

所以,从启动后台服务的角度来看,BroadcastReceiver不在前台。