### **[后臺執行限制](https://developer.android.com/about/versions/oreo/background.html)**
每次在后臺運行時,應用都會消耗一部分有限的設備資源,例如 RAM。 這可能會影響用戶體驗,如果用戶正在使用占用大量資源的應用(例如玩游戲或觀看視頻),影響尤為明顯。
為了提升用戶體驗,Android 8.0 對應用在后臺運行時可以執行的操作施加了限制。 本文檔說明了操作系統的一些變更,以及如何更新應用以便在新限制下正常運行。
#### **概覽**
多個 Android 應用和服務可以同時運行。 例如,用戶可以在一個窗口中玩游戲,同時在另一個窗口中瀏覽網頁,并使用第三個應用播放音樂。
同時運行的應用越多,對系統造成的負擔越大。 如果還有應用或服務在后臺運行,這會對系統造成更大負擔,進而可能導致用戶體驗下降;例如,音樂應用可能會突然關閉。
為了降低發生這些問題的幾率,Android 8.0 對應用在用戶不與其直接交互時可以執行的操作施加了限制。
應用在兩個方面受到限制:
* 后臺服務限制:處于空閑狀態時,應用可以使用的后臺服務存在限制。 這些限制不適用于前臺服務,因為前臺服務更容易引起用戶注意。
* 廣播限制:除了有限的例外情況,應用無法使用清單注冊隱式廣播。 它們仍然可以在運行時注冊這些廣播,并且可以使用清單注冊專門針對它們的顯式廣播。
> 注:默認情況下,這些限制僅適用于針對 O 的應用。 不過,用戶可以從 Settings 屏幕為任意應用啟用這些限制,即使應用并不是以 O 為目標平臺。
在大多數情況下,應用都可以使用 JobScheduler 作業克服這些限制。 這種方式讓應用安排為在未活躍運行時執行工作,不過仍能夠使系統可以在不影響用戶體驗的情況下安排這些作業。
Android 8.0 提供針對 JobScheduler 的多個改進,讓您可以更輕松地使用計劃作業取代服務和廣播接收器;如需了解詳細信息,請參閱 JobScheduler 改進。
#### **后臺服務限制**
在后臺中運行的服務會消耗設備資源,這可能降低用戶體驗。 為了緩解這一問題,系統對這些服務施加了一些限制。
系統可以區分 前臺 和 后臺 應用。 (用于服務限制目的的后臺定義與內存管理使用的定義不同;一個應用按照內存管理的定義可能處于后臺,但按照能夠啟動服務的定義又處于前臺。)如果滿足以下任意條件,應用將被視為處于前臺:
* 具有可見 Activity(不管該 Activity 已啟動還是已暫停)。
* 具有前臺服務。
* 另一個前臺應用已關聯到該應用(不管是通過綁定到其中一個服務,還是通過使用其中一個內容提供程序)。 例如,如果另一個應用綁定到該應用的服務,那么該應用處于前臺:
* IME
* 壁紙服務
* 通知偵聽器
* 語音或文本服務
如果以上條件均不滿足,應用將被視為處于后臺。
> 綁定服務不受影響
> 這些規則不會對綁定服務產生任何影響。 如果您的應用定義了綁定服務,則不管應用是否處于前臺,其他組件都可以綁定到該服務。
處于前臺時,應用可以自由創建和運行前臺服務與后臺服務。 進入后臺時,在一個持續數分鐘的時間窗內,應用仍可以創建和使用服務。
在該時間窗結束后,應用將被視為處于 空閑 狀態。 此時,系統將停止應用的后臺服務,就像應用已經調用服務的“Service.stopSelf()”方法。
在這些情況下,后臺應用將被置于一個臨時白名單中并持續數分鐘。 位于白名單中時,應用可以無限制地啟動服務,并且其后臺服務也可以運行。
處理對用戶可見的任務時,應用將被置于白名單中,例如:
* 處理一條高優先級 Firebase 云消息傳遞 (FCM) 消息。
* 接收廣播,例如短信/彩信消息。
* 從通知執行 PendingIntent。
在很多情況下,您的應用都可以使用 JobScheduler 作業替換后臺服務。 例如,CoolPhotoApp 需要檢查用戶是否已經從朋友那里收到共享的照片,即使該應用未在前臺運行。
之前,應用使用一種會檢查其云存儲的后臺服務。 為了遷移到 Android 8.0,開發者使用一個計劃作業替換了這種后臺服務,該作業將按一定周期啟動,查詢服務器,然后退出。
在 Android 8.0 之前,創建前臺服務的方式通常是先創建一個后臺服務,然后將該服務推到前臺。
Android 8.0 有一項復雜功能;系統不允許后臺應用創建后臺服務。 因此,Android 8.0 引入了一種全新的方法,即 Context.startForegroundService(),以在前臺啟動新服務。
在系統創建服務后,應用有五秒的時間來調用該服務的 startForeground() 方法以顯示新服務的用戶可見通知。
如果應用在此時間限制內未調用 startForeground(),則系統將停止服務并聲明此應用為 ANR。
#### **廣播限制**
如果應用注冊為接收廣播,則在每次發送廣播時,應用的接收器都會消耗資源。 如果多個應用注冊為接收基于系統事件的廣播,這會引發問題;觸發廣播的系統事件會導致所有應用快速地連續消耗資源,從而降低用戶體驗。
為了緩解這一問題,Android 7.0(API 級別 25)對廣播施加了一些限制,如后臺優化中所述。
Android 8.0 讓這些限制更為嚴格。
* 針對 Android 8.0 的應用無法繼續在其清單中為隱式廣播注冊廣播接收器。 隱式廣播是一種不專門針對該應用的廣播。 例如,ACTION_PACKAGE_REPLACED 就是一種隱式廣播,因為它將發送到注冊的所有偵聽器,讓后者知道設備上的某些軟件包已被替換。
不過,ACTION_MY_PACKAGE_REPLACED 不是隱式廣播,因為不管已為該廣播注冊偵聽器的其他應用有多少,它都會只發送到軟件包已被替換的應用。
* 應用可以繼續在它們的清單中注冊顯式廣播。
* 應用可以在運行時使用 Context.registerReceiver() 為任意廣播(不管是隱式還是顯式)注冊接收器。
* 需要簽名權限的廣播不受此限制所限,因為這些廣播只會發送到使用相同證書簽名的應用,而不是發送到設備上的所有應用。
在許多情況下,之前注冊隱式廣播的應用使用 JobScheduler 作業可以獲得類似的功能。
例如,一款社交照片應用可能需要不時地執行數據清理,并且傾向于在設備連接到充電器時執行此操作。
之前,應用已經在清單中為 ACTION_POWER_CONNECTED 注冊了一個接收器;當應用接收到該廣播時,它會檢查清理是否必要。 為了遷移到 Android 8.0,應用將該接收器從其清單中移除。
應用將清理作業安排在設備處于空閑狀態和充電時運行。
> 注:很多隱式廣播當前均已不受此限制所限。 應用可以繼續在其清單中為這些廣播注冊接收器,不管應用針對哪個 API 級別。 有關已豁免廣播的列表,請參閱隱式廣播例外。
#### **遷移指南**
默認情況下,這些更改僅影響針對 O 的應用。 不過,用戶可以從 Settings 屏幕為任意應用啟用這些限制,即使應用并不是以 O 為目標平臺。
您可能需要更新應用,使其符合新限制。
了解您的應用如何使用服務。 如果您的應用依賴某些在它處于空閑時于后臺運行的服務,您需要替換這些服務。
可能的解決方法包括:
* 如果處于后臺時您的應用需要創建一個前臺服務,請使用新的 NotificationManager.startServiceInForeground()
* 方法,而不是創建一個后臺服務,然后嘗試將其推到前臺。
* 如果服務容易被用戶注意,請將其設為前臺服務。 例如,播放音頻的服務始終應為前臺服務。
使用 NotificationManager.startServiceInForeground()
而不是 startService() 創建服務。 * 尋找一種使用計劃作業實現服務功能的方式。 如果服務未在執行容易立即被用戶注意到的操作,一般情況下,您都能夠使用計劃作業。
* 發生網絡事件時,請使用 FCM 選擇性地喚醒您的應用,而不是在后臺輪詢。
* 在應用正常處于前臺之前,請推遲后臺工作。
檢查在您應用的清單中定義的廣播接收器。 如果您的清單為顯式廣播聲明了接收器,您必須予以替換。 可能的解決方法包括:
* 通過調用 Context.registerReceiver() 而不是在清單中聲明接收器的方式在運行時創建接收器。
* 使用計劃作業檢查條件是否會觸發隱式廣播。
- 前言
- Google官網對Android API各版本的介紹
- jelly Bean(果凍豆)Android 4.1、4.2、4.3
- Android 4.1
- Android 4.2
- Android 4.3
- KitKat(Android 4.4.*)巧克力
- Android 4.4 APIS
- Lollipop(棒棒糖)Android 5.*
- Android 5.0 APIs
- Android 5.0 Changes(變更)
- Android 5.1APIs
- Marshmallow(棉花糖)Android 6.0
- Android 6.0 APIs
- Android 6.0 Changes(變更)
- Android 6.0 Samples
- Android 6.0 Testing
- Nougat(牛扎塘)Android 7.*
- Android 7.0
- API
- 行為變更
- 示例
- Android 7.1
- 開發者API
- 示例Sample
- Oreo(奧利奧)8.*
- Android 8.0
- 功能和 API
- Android 8.0 行為變更
- 向 Android 8.0 遷移應用
- Android 8.0 示例
- Android 8.1
- 后臺執行限制
- 后臺位置限制
- API指南
- Android 簡介
- 應用基礎知識
- 設備兼容性
- 系統權限
- 請求權限
- 定義權限
- 平臺架構
- Java8 概覽
- 在ART上驗證應用行為
- 應用組件
- Intent 和 Intent 過濾器(Google官網介紹)
- 通用intent
- Activity
- 任務和返回棧(官網譯文)
- 概覽屏幕
- 活動簡介
- 活動生命周期
- 活動狀態更改
- 進程和應用程序生命周期
- 包裹和捆綁
- 最近的屏幕
- 片段
- 加載器
- 服務Service
- 綁定服務
- AIDL
- 內容提供程序
- 內容提供程序基礎知識
- 創建內容提供程序
- 日歷提供程序
- 聯系人提供程序
- 存儲訪問框架
- 使用存儲訪問框架打開文件
- 創建自定義文檔提供程序
- 應用小部件
- 應用小部件主機
- 進程和線程
- 應用資源
- 概覽
- 提供資源
- 訪問資源
- 處理運行時變更
- 本地化
- ICU4J Android框架API
- Android上的國際化
- 語言和語言區域
- 復雜的XML資源
- 資源類型
- 動畫
- 顏色狀態列表
- 可繪制對象
- 布局
- 菜單
- 字符串
- 樣式
- 其他類型
- 應用清單
- <action>
- <activity>
- <activity-alias>
- <application>
- <category>
- <compatiable-screens>
- <data>
- <grant-uri-permission>
- <intent-filter>
- <manifest>
- <meta-data>
- <path-permission>
- <permission>
- <permission-group>
- <permission-tree>
- <provider>
- <receiver>
- <service>
- <supporte-gl-texture>
- <supports-screens>
- <uses-configuration>
- <uses-feature>
- <uses-library>
- <uses-permission>
- <uses-permission-sdk-23>
- <uses-sdk>
- 用戶界面
- 界面概覽
- 界面布局
- 線性布局
- 相對布局
- 列表視圖
- 網格視圖
- 回收站視圖
- 外觀和感覺
- 可下載的字體
- XML中的字體
- 表情符號兼容性
- 自動調整TextView
- 樣式和主題-
- 輸入控件
- 按鈕
- 文本字段
- 復選框
- 單選按鈕
- 切換按鈕
- 微調框
- 選取器
- 輸入事件
- 菜單Menu
- 設置
- 對話框
- 通知
- Toast
- 自適應圖標
- 應用快捷方式
- 搜索
- 創建搜索界面
- 添加近期查詢建議
- 添加自定義建議
- 可搜索配置
- 多窗口支持
- 拖放
- 無障礙功能
- 為應用設置無障礙功能
- 無障礙功能開發者檢查單
- 構建無障礙服務
- 讓應用更容易訪問
- 使用節點樹調試
- 構建可訪問自定義視圖
- 樣式和主題
- 自定義組件
- 動畫和圖形
- 概覽介紹
- 屬性動畫
- 視圖動畫
- 可繪制動畫
- 畫布和可繪制對象
- 基于物理的動畫
- Spring Animation
- Fling Animation
- OpenGL ES
- 硬件加速
- 計算
- RenderScript
- 高級RenderScript
- Runtime API Reference(參考)
- Numerical Types(數字類型)
- Object Types(對象類型)
- Conversion Functions(轉換函數)
- Mathematical Constants and Functions(數學常量和函數)
- Vector Math Functions(矢量數學函數)
- Matrix Functions(矩陣函數)
- Quaternion Functions(四元數函數)
- Atomic Update Functions(原子更新函數)
- Time Functions and Types(時間函數和類型)
- Allocation Data Access Functions(分配數據訪問函數)
- Object Characteristics Functions(對象特性函數)
- Kernel Invocation Functions and Types(內核調用函數和類型)
- Input/Output Functions(輸入輸出函數)
- Debugging Functions(調試函數)
- Graphics Functions and Types(圖形函數和類型)
- Index(索引)
- Media Apps(媒體應用)
- Media Apps Overview(媒體應用程序概述)
- Working with a Media Session(使用媒體會話)
- Building an Audio App(建立一個音頻應用)
- Building a Media Browser Service(構建媒體瀏覽器服務)
- Building a Media Browser Client(構建媒體瀏覽器客戶端)
- Media Session Callbacks(媒體會話回調)
- Building a Video App(建立一個視頻應用)
- Building a Video Player Activity(建立一個視頻播放器Activity)
- Media Session Callbacks-(媒體會話回調)
- Responding to Media Buttons(響應媒體按鈕)
- Handling Changes in Audio Output(處理音頻輸出的變化)
- Managing Audio Focus(管理音頻焦點)
- The Google Assistant and Media Apps(Google智能助理和媒體應用)
- 媒體和相機
- Supported Media Formats(支持的媒體格式)
- MediaPlayer(媒體播放器)
- MediaRecorder
- ExoPlayer
- Controller Amplitude with VolumeShaper(VolumeShaper控制器振幅)
- Media Routing(媒體路由)
- MediaRouter API
- MediaRouteProvider API
- Camera API(相機API)
- 位置和傳感器
- Location and Maps(位置和地圖)
- Location Strategies(位置策略)
- Sensors Overview(傳感器概覽)
- Motion Sensors(運動傳感器)
- Position Sensors(位置傳感器)
- Environment Sensors(環境傳感器)
- Raw GNSS Measurements(原始的GNSS測量)
- 連接
- Bluetooth
- Bluetooth Low Energy(藍牙低功耗)
- NFC
- NFC Basics(NFC基礎知識)
- Advanced NFC(高級NFC)
- Host-based Card Emulation(基于主機的卡模擬)
- Telecom(電信)
- Self-Managed ConnectionServices(自我管理的連接服務)
- Wi-Fi P2P
- Wi-Fi Aware
- Companion Device Pairing
- USB
- Accessory(配件)
- Host(主機)
- SIP
- 文本和輸入
- Autofill Framework(自動填充框架)
- Test your app with autofill(使用自動填充測試你的應用)
- Building autofill services(構建自動填充服務)
- Copy and Paste(復制和粘貼)
- Creating an IME(創建IME)
- Image Keyboard(圖像鍵盤)
- Spelling Checker(拼寫檢查程序)
- 數據存儲
- Storage Options(存儲選項)
- Data Backup(數據備份)
- Account Transfer API(賬戶轉移API)
- Auto Backup(自動備份)
- Key/Value Backup(鍵值備份)
- Testing Backup and Restore(測試備份和還原)
- App Install Location(應用安裝位置)
- 庫
- 支持庫
- 功能
- 修訂歷史記錄
- 庫設置
- 數據綁定庫
- 測試支持庫
- 管理
- 設備策略
- 網絡應用
- Supporting Different Screens in Web Apps(在網絡應用中支持不同屏幕)
- Building Web Apps in WebView(在WebView中構建網絡應用)
- Managing WebViews
- Migrating to WebView in Android 4.4(遷移到Android4.4中的WebView)
- Debugging Web Apps(調試網絡應用)
- Best Practices for Web Apps(網絡應用最佳做法)
- 最佳實踐
- Supporting Multiple Screens(支持多種屏幕)
- Distributing to Specific Screens(分配到特定屏幕)
- Screen Compatibility Mode(屏幕兼容性模式)
- Designing for Seamlessness
- Supporting Tablets and Handsets
- 培訓