android java service_Android8.0 启动后台Service

在一加手机上,用户升级了新版8.0的系统,用户将app切到后台,过一会儿就弹出“xxx app 已停止运行”的弹窗。

通过定位分析,发现下面俩前置条件

8.0系统杀服务杀的很频繁

为了保活,我们使用了俩Service互保的方式

马上跑了26的模拟器,果然复现,日志如下:

main

Process: com.icourt.alpha.service.LocalService, PID: 4343

java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.icourt.alpha/.service.LocalService }: app is in background uid UidRecord{81da92c u0a91 SVC bg:+1m0s13ms idle procs:4 seq(0,0,0)}

at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1505)

at android.app.ContextImpl.startService(ContextImpl.java:1461)

at android.content.ContextWrapper.startService(ContextWrapper.java:644)

at com.icourt.alpha.service.RemoteService$RemoteServiceConnection.onServiceDisconnected(RemoteService.java:100)

at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1627)

at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1663)

at android.os.Handler.handleCallback(Handler.java:789)

at android.os.Handler.dispatchMessage(Handler.java:98)

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)

我查阅了android官网,有如下一段描述:

Android 8.0 还对特定函数做出了以下变更:

如果针对 Android 8.0 的应用尝试在不允许其创建后台服务的情况下使用 startService() 函数,则该函数将引发一个 IllegalStateException。

新的 Context.startForegroundService() 函数将启动一个前台服务。现在,即使应用在后台运行,系统也允许其调用 Context.startForegroundService()。不过,应用必须在创建服务后的五秒内调用该服务的 startForeground() 函数。

解决方法就很简单了,把Service互启的逻辑块改为:

if (Build.VERSION.SDK_INT >= 26) {

context.startForegroundService(intent);

} else {

// Pre-O behavior.

context.startService(intent);

}

有个简写:ContextCompat.startForegroundService(context, intent)

因为我不想让用户在控制面板看到通知栏,我没有在创建服务后的五秒内调用startForeground()。我马上试了一下,果然没有了“已停止运行”,但是日志爆出了另一个ANR的错误,虽然不是在主线程,也没有弹窗,但毕竟是个错误,我想一探究竟。

回到官方的描述:在被启动的Service创建服务后的五秒内调用startForground(0, new Notification()),如果不调用或调用时间超过5秒会抛出一个ANR。

果不其然,我只有调用了,这样更好,有前台进程,系统想杀都杀不掉了。

但仔细看一下官方文档,你会发现,官方推荐使用JobScheduler,这是api25的新特性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值