在应用程序启动时,应用程序启动应该执行某些网络任务的服务。以 API 级别 26 为目标后,我的应用程序无法在后台在 Android 8.0 上启动服务。
原因:java.lang.IllegalStateException:不允许启动服务 Intent { cmp=my.app.tt/com.my.service }:应用处于后台 uid UidRecord{90372b1 u0a136 CEM idle procs:1 seq(0,0 ,0)}
据我了解,它与: 后台执行限制有关
如果面向 Android 8.0 的应用尝试在不允许创建后台服务的情况下使用该方法,则 startService() 方法现在会引发 IllegalStateException。
“ 在不允许的情况下 ”-实际上是什么意思?以及如何解决它。我不想将我的服务设置为“前台”
允许的情况是临时白名单,其中后台服务的行为与 Android O 之前的行为相同。
在某些情况下,后台应用程序会被置于临时白名单中几分钟。当应用在白名单中时,它可以不受限制地启动服务,并且允许其后台服务运行。当应用处理用户可见的任务时,应用会被列入白名单,例如: 处理高优先级 Firebase 云消息传递 (FCM) 消息。 接收广播,例如 SMS/MMS 消息。 从通知执行 PendingIntent。 在 VPN 应用程序将自身提升到前台之前启动 VpnService。
在某些情况下,后台应用程序会被置于临时白名单中几分钟。当应用在白名单中时,它可以不受限制地启动服务,并且允许其后台服务运行。当应用处理用户可见的任务时,应用会被列入白名单,例如:
来源:https ://developer.android.com/about/versions/oreo/background.html
所以换句话说,如果您的后台服务不符合白名单要求,您必须使用新的JobScheduler。它与后台服务基本相同,但它会定期调用,而不是在后台连续运行。
如果您使用的是 IntentService,则可以更改为 JobIntentService。请参阅下面的的回答。
最好的方法是使用JobIntentService,它使用新的 JobScheduler for Oreo 或旧服务(如果不可用)。
在您的清单中声明:
<service android:name=".YourService" android:permission="android.permission.BIND_JOB_SERVICE"/>
在您的服务中,您必须将 onHandleIntent 替换为 onHandleWork:
public class YourService extends JobIntentService { public static final int JOB_ID = 1; public static void enqueueWork(Context context, Intent work) { enqueueWork(context, YourService.class, JOB_ID, work); } @Override protected void onHandleWork(@NonNull Intent intent) { // your code } }
然后你开始你的服务:
YourService.enqueueWork(context, new Intent());