Android 8.0启动Service问题

起因

今天在和同事定义一个Bug,该Bug具体情况为我们的应用在开机后收到开机广播在Application中启动Service报错,报错内容如下。记录下Bug处理过程及定位结果以备不时之需。

java.lang.RuntimeException: Unable to instantiate application 【包名被我替换了】: java.lang.IllegalStateException: Not allowed to start service Intent

经过

由于我们是定制化系统,是可以收到开机广播的,所以不要纠结开机广播的问题。Android原生OS在已经禁用了开机广播,第三方应用是无法收到开机广播的。
根据同事定位我们的应用在开机的时候出现Crash,如果开机后从应用入口进入可正常运行,并且在Android8.0上是必现的。查看我们应用的源码找到两处关键log,一个位于startService()处,一个位于Service的onCreate()方法中。
获取测试反馈log,进行log搜索,找到crash时和正常启动时的关键log及关键log附近的log。对比log后发现:
【出错时log】:ResourceManagerService: emmm, isCaller Fg Not Directly return false
ResourceManagerService: package 【包名被我替换了】is bg!
ResourceManagerService: 【包名被我替换了】 is not found in 白名单.
【正常时log】:ResourceManagerService: package 【包名被我替换了】is fg!
看这情况应该是由于我们的应用是后台进程的问题,出错时是后台进程,正常时是前台进程。问了下系统开发的同事,的确是这样的!!!我们的进程是后台进程,Android8.0及以后在原生OS的逻辑中是直接抛异常的。我们的系统加入了白名单的判断,由于我们的应用没在白名单里,所以就startService()报异常了。正常启动时由于是前台行为,我们的进程在startService()时是前台进程,所以可以直接启动。原生OS对于前台进程也是如此处理的。
定位了问题后,解决就很简单了,由于我们的是定制化操作系统,直接把我们应用加白名单就行了!!!

结果

Android原生8.0及以后的操作系统中对startService()做了限制,如果在后台应用中调用startService()将抛出异常。如果是前台进程,则可以正常运行。对于后台进程调用startService()需改为startForegroundService(),前台进程可以正常调用startService()。

你可能感兴趣的:(Android)