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

查看:349
本文介绍了带有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)

如何正确执行此操作?

推荐答案

以下是我在您的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天全站免登陆