詳解:android O 對Service的限制【Background Execution Limits】

目錄

  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後臺運行都會被系統限制。java

知足如下兩個特色的APP,內的Service,可能會受到系統限制android

  • 必須在android 8.0以上的設備上bash

  • APP的 targetSdkVersion 配置大於等於26app

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

    android {
            defaultConfig {
                targetSdkVersion 26 //此配置
            }
            ...
        }
    複製代碼



2. android O 對Service增長了哪些限制?

當APP處於空閒期時,將會有以下兩個限制:oop

  • 主動調用 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()生命週期方法。post


注意:gradle

這裏千萬要注意,理解:app處在空閒期,是什麼意思?ui

空閒期,在,官方文檔的英文描述爲:idle。google

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.im/post/5dd16f…

請注意,當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
相關文章
相關標籤/搜索