运行时异常 Android O 与boot_completed



我正在尝试在我的BOOT_COMPLETED接收器中启动一个意图服务,但在Android O(API 26)中,我得到:

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

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

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

以下是我在博客文章中概述的一些选项:

解决方法 #1:启动前台服务()

接收ACTION_BOOT_COMPLETED广播的BroadcastReceiver在安卓上可以拨打startForegroundService()而不是startService()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 中收到一个错误:

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(),在这种情况下,您可以 正常执行后台工作,尽管用户通知中显示了一个条目 阴影。

解决方法 #2:goAsync()

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

解决方法 #3:作业计划程序

如果您的工作将花费几秒钟以上,并且您想避免Notification,您可以修改代码以实现JobService和 与JobScheduler合作。这还有一个额外的优势,那就是只给你 控制何时满足其他条件(例如,存在可用的互联网 连接)。但是,这不仅需要重写,而且需要JobScheduler仅适用于 Android 5.0+,因此如果您的minSdkVersion低于 21, 您将需要在旧设备上使用其他解决方案。

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

您可能需要查看Android O行为更改文档的以下部分 https://developer.android.com/preview/features/background.html#services

它现在限制应用何时能够启动后台服务。

相关内容

  • 没有找到相关文章

最新更新