以下是我概述的一些选项一篇博文 https://commonsware.com/blog/2017/06/12/action_boot_completed-intentservice-android-8p0.html:
解决方法#1:startForegroundService()
Your BroadcastReceiver
接收到的ACTION_BOOT_COMPLETED
播送
可以打电话startForegroundService()
代替startService()
在 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 中得到一个错误:
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
简而言之,不客气
使用startForeground()
正如 Android 所期望的那样,在这种情况下您可以
正常进行后台工作,尽管用户通知中显示了一个条目
树荫。
解决方法#2:goAsync()
BroadcastReceiver
已提供goAsync()
从 API 级别 11 开始。这允许您
接收器在主应用程序线程之外完成工作,因此您可以摆脱IntentService
完全并将您的代码移入BroadcastReceiver
。
您仍然只有 ANR
使用超时期限,但您不会占用您的主应用程序
线。这比第一个解决方法更好,因为它具有相同的功能
时间限制但避免了令人讨厌的错误。不过确实需要一定的金额
返工。
解决方法#3:JobScheduler
如果您的工作需要花费几秒钟以上and你想避免Notification
,你可以修改你的代码来实现JobService
和
与...一起工作JobScheduler
。这还有一个额外的好处,那就是只给你
当满足其他标准时进行控制(例如,有可用的互联网
联系)。然而,这不仅需要重写,而且JobScheduler
仅适用于 Android 5.0+,所以如果您minSdkVersion
小于21,
您将需要在旧设备上使用其他解决方案。
UPDATE:尤金·佩查内克指出JobIntentService https://twitter.com/EPechanec/status/874347355058962433,
这是一个有趣的JobService
/IntentService
mashup.