带有boot_completed的运行时异常Android O [英] Runtime exception Android O with boot_completed
问题描述
我试图在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)
如何正确执行此操作?
推荐答案
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间隔".
如果您的工作时间超过一毫秒,但少于几秒钟,
您可以跳过Notification
和startForeground()
调用.然而,
您会在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屋!