我们的应用针对的是Android O.
在阅读Background Service Limitation之后,我注意到前台应用程序启动服务是安全的。因此,在我们的应用程序中,我们在Fragment的startService()
方法中调用了onStart()
。我们认为这是可以的,因为在this document中它表示当调用onStart时,片段对用户可见,并且当它可见时,它意味着此应用程序是前景应用程序。
但有时,我必须承认这种情况非常罕见,我们仍然会收到以下异常
java.lang.IllegalStateException:不允许启动服务Intent {act = ACTION_DEACTIVATE cmp = com.adyxe.sync / .ClientService}:app在后台uidReidRedord {db2a697 u0a19最后bg:+ 7m30s540ms空闲更改:缓存过程:1 seq (0,0,0)}
为什么会这样?在onResume()
中调用startService()更安全,只是为了更确定该应用程序现在是一个前台应用程序吗?
首先,您可能在Android中发现了一个错误:)
无论如何,你应该使用JobIntentService
并将其排队。
这样,当应用程序被考虑在前台时,系统将运行您的服务,您将看不到错误。在pre-Oreo版本中,无论应用程序前景状态如何,服务都应立即运行。
这是一个例子:
public class ExampleJobIntentService extends JobIntentService {
static final int JOB_ID = 1000;
static void enqueueWork(Context context, Intent work) {
enqueueWork(context, ExampleJobIntentService.class, JOB_ID, work);
}
@Override
public void onCreate() {
super.onCreate();
// Some initializations...
}
@Override
protected void onHandleWork(Intent work) {
// Do your stuff...
}
@Override
public boolean onStopCurrentWork() {
// return true to reschedule this service if your work failed.
return false;
}
}
然后你像这样排队:
// The intent is the one that will be received here: onHandleWork(Intent work)
ExampleJobIntentService.enqueueWork(context, intent);
在Manifest
中注册,如下所示:
<service
android:name=".ExampleJobIntentService"
android:permission="android.permission.BIND_JOB_SERVICE" />
如果您计划在后台运行该服务,则应在WAKE_LOCK
中为pre-Oreo版本添加Manifest
权限:
<uses-permission android:name=”android.permission.WAKE_LOCK” />