详解:android O 对Service的限制【Background Execution Limits】

4,449 阅读5分钟

目录

  1. 哪些APP内的Service后台运行会被系统限制?
  2. android O 【即android8.0】对Service增加了哪些限制?
  3. 疑惑:
    1. 存在通知栏的App,是否属于前台APP?
    2. 如何判断App处在后台?
    3. 如何判断APP处在空闲期?
    4. 如何做到:APP进入空闲期时,不让系统立即回收Service, 启动Service不Crash。
  4. 官方文档
  5. 官方文档摘抄重要部分



1. 哪些app的Service后台运行会被系统限制?

首先并不是所有app的Service后台运行都会被系统限制。

满足以下两个特点的APP,内的Service,可能会受到系统限制

  • 必须在android 8.0以上的设备上

  • APP的 targetSdkVersion 配置大于等于26

    APP的targetSdkVersion的配置在app/build.gradle文件中

        android {
            defaultConfig {
                targetSdkVersion 26 //此配置
            }
            ...
        }
    



2. android O 对Service增加了哪些限制?

当APP处于空闲期时,将会有如下两个限制:

  • 主动调用 Context.startService() 将引发crash。崩溃日志,如下:
java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.compat.test/com.test.Service4 }: app is in background uid UidRecord{a0d4e51 u0a84 CEM  bg:+1m2s21ms idle procs:1 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.test.MainActivityV2$8.run(MainActivityV2.java:153)
        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)



  • 对于普通的Service,App进入空闲期后,系统将会立即停止并回收该服务

被回收的现象,就和我们自己主动调用Context.stopService()一样。 Service将会被执行:onDestory()生命周期方法。


注意:

这里千万要注意,理解:app处在空闲期,是什么意思?

空闲期,在,官方文档的英文描述为:idle。

app处在后台,并不等于处在空闲期;

app处在后台,并不等于处在空闲期;

app处在后台,并不等于处在空闲期;

APP处于后台,是进入空闲期的必要条件,但不是充分条件。


例如:

​ Model PixelXL手机, android8.0.0系统:在APP进入后台状态,并保持处于后台状态1分钟后,才进入空闲期。

​ APP从开始处于后台,到,正式进入空闲期的 这1分钟期间,app可以随意startService是不会抛出异常的。App内的Service也不会被系统主动回收。

​ 在这1分钟期间,用户如果打开APP,将APP置为前台,那么下次进入后台后需要重新计时,重新进入后台保持1分钟才会进入空闲期。



3. 我们心中可能会产生5个疑问

  1. APP存在常驻通知栏时,是否属于前台APP?

  2. APP什么情况下会进入空闲期?

  3. 如何判断App处在后台?

  4. APP进入空闲期时,如何防止Service不被Stop

  5. APP处在空闲期时,如何启动Service,不引发Crash


  • APP存在常驻通知栏时,是否属于前台APP?

如果只是普通的通知栏,并没有什么卵用的。

只有通过 Service.startForeground(int id, Notification notification) 启动的通知栏,才能让app成为前台APP。

如下图,前台Service的通知栏。

前台通知栏

再次强调,通过 NotificationManager.notify(int id, notification) 显示的普通通知,不会让app成为前台APP,也不会让进程成为前台进程。必须通过Service.startForeground(int id, Notification notification)方法现实的通知栏才有用。


  • APP什么情况下会进入空闲期?

APP处于后台之后,并不会立即进入空闲期,需要过几分钟,官方文档并没有明确时长。

Model PixelXL android8.0.0 在app进入后台状态1分钟后才进入空闲期;

在模拟器上也是1分钟后进入空闲期;


  • 那么如何判断App处在后台?这里有点复杂,需要耐心捋一捋。

    满足以下任一,一个条件的APP都属于前台,Service运行不受任何限制。

    • app存在一个可见的Activity,Activity处于started或者paused或者resume阶段
    • app中有一个前台Service【即主动吊用过startForeground(int id, Notification notification)的Service】
    • app被另一个前台app通过Service、Content Provider 绑定或者连接,比如说:
    • IME 输入法APP,被系统的前台进程绑定【或者我们APP中的一个Service,被其他第三方APP绑定,当第三方APP处在前台时,那么我们的APP也是处在前台的。】
    • Wallpaper service
    • Notification listener
    • Voice or text service



  • **如何突破Android O Service **

详见:下篇,突破android o Service限制juejin.cn/post/684490…

请注意,当APP处于前台时,他的所有Service是不受限制的。

比如说,输入法APP永远是一个前台APP,他被系统的前台进程绑定,所以他Service的能力永远不会被限制。

再比如说,如果APP有可见Activity时,在APP中可以随意调用Context.startService(),也不会引发crash。



4. 官方链接:

developer.android.google.cn/about/versi…

英语基础好的盆友,强烈建议,把整片官方文档读一遍。


5. 摘抄官方文档,解释:前后台APP,以及空闲期

The system distinguishes between foreground and background apps. (The definition of background for purposes of service limitations is distinct from the definition used by memory management; an app might be in the background as pertains to memory management, but in the foreground as pertains to its ability to launch services.)An app is considered to be in the foreground if any of the following is true:

1) It has a visible activity, whether the activity is started or paused.
2) It has a foreground service.
3) Another foreground app is connected to the app, either by binding to one of its services or by making use of one of its content providers. For example, the app is in the foreground if another app binds to its:
    a. IME
    b. Wallpaper service
    c. Notification listener
    d. Voice or text service
If none of those conditions is true, the app is considered to be in the background.



点这里,查看大叔的博客大纲







​ 赞美是一种美德,点个赞再走啊,老铁

weixin_2dcode
关键词:Android O 新特性 - Background Execution Limits; android8.0 后台执行限制; 后台Service限制; Background Service Limitations; android O适配; android8.0适配; Service适配; 后台启动启动service。