Android 8.0 后台应用无法启动服务源码分析

都知道在Android8.0设备上,后台应用无法通过startService方式启动后台服务,如果使用这种方式启动,之间会抛出异常:java.lang.IllegalStateException: Not allowed to start service Intent { cmp=xxx }: app is in background uid UidRecord{xxx},异常会提示你的应用是后台应用,不允许启动服务。

在谷歌官网上有以下描述:

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

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

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

对于如何解决,官网上也给了我们解决方案,调用startForegroundService()函数,而且创建服务后5s内需要调用该服务的startForeground()函数,但是这种方式会在前台创建一个通知栏,用户可以感知的到。

下面从源码中尝试去寻找一下,看有没有其他的解决方案。

首先,我们调用了Context的startService方法,其实最终调用的是android.app.ContextImpl的startService方法。

在该方法中又调用了它的startServiceCommon()方法,该方法中会抛出上面打印的异常,在当包名是“?”的时候,才会进入该分支,而包信息又是通过ActivityManagerService的startService()方法获取的,因此继续查看ActivityManagerService的startService()方法。


在ActivityManagerService中的startService方法中,继续调用了ActiveServices的startServiceLocked方法,如下:


在该方法中会有如下一段代码,首先会去判断它的启动类型是不是APP_START_MODE_NORMAL,如果不是的话,会进入当前分支,在最后会return一个新的ComponentName,指定了它的pkg为"?",并且指定了当前应用时后台应用,此时和ActivityManagerService的startService()方法中能够对应上。

下面继续看看allowed是怎么指定的。


allowed是通过调用ActivityManagerService的getAppStartModeLocked获取的,由于程序已经抛出异常,因此我们从上面代码可以知道,allowed类型既不是APP_START_MODE_NORMAL,也不是APP_START_MODE_DELAYED,并且alwaysRestrict参数传值为false。然后继续查看getAppStartModeLocked函数可以看到以下代码,可以看出来最终allowed是通过startMode赋值,并且是通过appServicesRestrictedInBackgroundLocked()函数获取的。


下面我们继续查看appServicesRestrictedInBackgroundLocked()函数。

这个函数中做了三件事情:

1.判断我们的应用是否是persistent app,具体什么是persistent app,可查看https://blog.csdn.net/u011959433/article/details/70324511

2.判断我们的应用是否加入到后台白名单中,如果是,直接返回APP_START_MODE_NORMAL类型

3.判断我们应用是否加入到电池白名单中


找到这块问题就很明了了,因为我们的应用这三种都不满足,因此会抛出上述异常。那怎么去解决呢,只要能让我们的应用startMode返回值为APP_START_MDOE_NORMAL类型,这个问题就可以解决,并且不用担心会弹出一个通知栏,让用户感知到。

但是这种方式解决只能适用系统开发时使用,普通应用无法采用这种方式解决,如果非要采用这种方式,那只能通过联系手机厂商,将自己的应用加入到他们的白名单中。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,738评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,377评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,774评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,032评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,015评论 5 361
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,239评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,724评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,374评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,508评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,410评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,457评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,132评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,733评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,804评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,022评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,515评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,116评论 2 341

推荐阅读更多精彩内容