带有 boot_completed 的运行时异常 Android O [英] Runtime exception Android O with boot_completed

查看:46
本文介绍了带有 boot_completed 的运行时异常 Android O的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在我的 BOOT_COMPLETED 接收器中启动 IntentService,但在 Android O (API 26) 中我得到:

I'm trying to start an IntentService within my BOOT_COMPLETED receiver, but in Android O (API 26) I get:

java.lang.RuntimeException: 
java.lang.IllegalStateException: 
Not allowed to start service Intent { act=intent.action.update cmp=packageName.services.OwnService }: 
app is in background

(消息在一行中,但这样更容易阅读)

(Message is in one line, but this way it's easier readable)

我怎样才能以正确的方式做到这一点?

How can I do this the correct way?

推荐答案

以下是我在 一篇博文:

您的 BroadcastReceiver 接收 ACTION_BOOT_COMPLETED 广播在 Android 上可以调用 startForegroundService() 而不是 startService()8.0+:

Your BroadcastReceiver that receives the ACTION_BOOT_COMPLETED broadcast could call startForegroundService() instead of startService() when on Android 8.0+:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;

public class OnBootReceiver extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {
    Intent i=new Intent(context, TestIntentService.class);

    if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.O) {
      context.startForegroundService(i);
    }
    else {
      context.startService(i);
    }
  }
}

请注意,这在一定程度上有效,即使您的服务实际上没有永远调用 startForeground().您有时间四处走动调用 startForeground(),与执行此操作的 ANR 间隔相当".如果您的工作时间长于一毫秒但少于几秒,您可以跳过 NotificationstartForeground() 调用.然而,你会在 LogCat 中得到一个错误:

Note that this works, to an extent, even if your service does not actually ever call startForeground(). You are given a window of time to get around to calling startForeground(), "comparable to the ANR interval to do this". If your work is longer than a millisecond but less than a few seconds, you could skip the Notification and the startForeground() call. However, you will get an error in LogCat:

E/AndroidRuntime: FATAL EXCEPTION: main
 Process: com.commonsware.myapplication, PID: 5991
 android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground()
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1775)
     at android.os.Handler.dispatchMessage(Handler.java:105)
     at android.os.Looper.loop(Looper.java:164)
     at android.app.ActivityThread.main(ActivityThread.java:6541)
     at java.lang.reflect.Method.invoke(Native Method)
     at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

当然,如果你不介意简短的Notification,欢迎你像 Android 期望的那样使用 startForeground(),在这种情况下,您可以正常进行后台工作,尽管在用户的通知中显示了一个条目阴影.

Of course, if you do not mind having a Notification briefly, you are welcome to use startForeground() as Android expects you to, in which case you can do background work normally, albeit with an entry showing up in the user's notification shade.

BroadcastReceiver 从 API 级别 11 开始提供 goAsync().这允许您接收器在主应用程序线程之外工作,这样你就可以摆脱IntentService 并将您的代码移动到 BroadcastReceiver 中.你仍然只有 ANR使用超时期限,但您不会占用主应用程序线.这比第一个解决方法要好,因为它具有相同的时间限制,但避免了令人讨厌的错误.但是,它确实需要一些数量返工.

BroadcastReceiver has offered goAsync() since API Level 11. This allows your receiver to do work off the main application thread, so you could get rid of the IntentService entirely and move your code into the BroadcastReceiver. You still only have the ANR timeout period to work with, but you will not be tying up your main application thread. This is better than the first workaround, insofar as it has the same time limitation but avoids the nasty error. However, it does require some amount of rework.

如果您的工作需要超过几秒钟并且您想避免Notification,你可以修改你的代码来实现一个 JobService 和使用 JobScheduler.这有一个额外的好处,就是只给你控制何时满足其他标准(例如,有可用的互联网联系).然而,这不仅需要重写,而且 JobScheduler仅适用于 Android 5.0+,因此如果您的 minSdkVersion 小于 21,您将需要在旧设备上使用其他解决方案.

If your work will take more than a few seconds and you want to avoid the Notification, you could modify your code to implement a JobService and work with JobScheduler. This has the added advantage of only giving you control when other criteria are met (e.g., there is a usable Internet connection). However, not only does this require a rewrite, but JobScheduler is only available on Android 5.0+, so if your minSdkVersion is less than 21, you will need some other solution on the older devices.

更新:Eugen Pechanec 指出JobIntentService,这是一个有趣的 JobService/IntentService 混搭.

UPDATE: Eugen Pechanec pointed out JobIntentService, which is an interesting JobService/IntentService mashup.

这篇关于带有 boot_completed 的运行时异常 Android O的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆