背景程序可能會耗用大量記憶體和電量。舉例來說 隱式廣播可能會啟動許多已註冊至 監聽模型,即使該程序可能執行了太多工作此功能可以 對裝置效能和使用者體驗造成重大影響。
為避免系統限制,請務必使用正確的 API 背景任務 背景工作總覽說明文件可協助您 以及符合自身需求的 API
使用者啟動限制
如果應用程式出現 Android Vitals 中描述的部分不良行為, 系統會提示使用者限制應用程式存取系統資源。
如果系統發現應用程式耗用過多資源,會發出通知 並提供選項讓使用者限制應用程式的動作。 可能觸發這類通知的行為包括:
- Wake Lock 過多:在螢幕關閉時,持續 1 小時的 1 個部分 Wake Lock 關閉
- 背景服務過多:如果應用程式指定的 API 級別低於 26 且背景服務過多
精確的限制項目由裝置製造商決定。適用對象 舉例來說,在 Android 開放原始碼計畫版本中,受限制的應用程式無法執行工作、觸發鬧鐘或使用 除非應用程式在前景執行。
接收網路活動廣播訊息的限制
如果應用程式已註冊 CONNECTIVITY_ACTION
,就不會收到其廣播訊息
並產生需要的廣播訊息
就不會啟動如果應用程式想要監聽網路,這可能會造成問題
變更或執行大量網路活動
非計量付費網路有數種可解決這項限制的解決方案
都已存在於 Android 架構中,但該如何選擇適合自己的工具
達成應用程式的目標
排定非計量付費連線的工作
建構 WorkRequest
時,請新增 NetworkType.UNMETERED
Constraint
。
fun scheduleWork(context: Context) {
val workManager = WorkManager.getInstance(context)
val workRequest = OneTimeWorkRequestBuilder<MyWorker>()
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED)
.build()
)
.build()
workManager.enqueue(workRequest)
}
符合工作條件時,應用程式會收到執行回呼
指定的 Worker
類別中的 doWork()
方法。
在應用程式執行時監控網路連線
執行中的應用程式仍可透過CONNECTIVITY_CHANGE
已註冊 BroadcastReceiver
,但 ConnectivityManager
API
提供了更強大的方法,只有在指定網路時才要求回呼
條件相符。
NetworkRequest
物件會定義
NetworkCapabilities
的條款。您可以建立 NetworkRequest
物件
呼叫 NetworkRequest.Builder
類別。registerNetworkCallback
敬上
然後將 NetworkRequest
物件傳遞至系統。連上網路後
如果符合條件,應用程式就會收到回呼,執行
onAvailable()
方法
ConnectivityManager.NetworkCallback
類別。
應用程式會持續收到回呼,直到應用程式結束或呼叫為止 unregisterNetworkCallback() 解析度。
接收圖片和影片廣播訊息的限制
應用程式無法收發 ACTION_NEW_PICTURE,或 ACTION_NEW_VIDEO 廣播訊息。這項限制有助於減輕 如果必須喚醒多個應用程式,效能和使用者體驗都會受到影響 來處理新圖片或影片
判別觸發工作的內容主機名稱
WorkerParameters
可讓應用程式接收與以下項目相關的實用資訊
內容主機名稱和 URI 觸發工作:
List<Uri> getTriggeredContentUris()
傳回觸發工作的 URI 清單。如果 沒有任何 URI 觸發作業 (例如,作業因 期限或其他原因),或發生變更的 URI 數量大於 50.
List<String> getTriggeredContentAuthorities()
傳回觸發作業的內容主機名稱字串清單。如果
傳回的清單並非空白,請使用 getTriggeredContentUris()
來擷取
並詳述已變更的 URI
下列程式碼範例會覆寫 CoroutineWorker.doWork()
方法
並記錄觸發工作的內容主機名稱和 URI:
class MyWorker(
appContext: Context,
params: WorkerParameters
): CoroutineWorker(appContext, params)
override suspend fun doWork(): Result {
StringBuilder().apply {
append("Media content has changed:\n")
params.triggeredContentAuthorities
.takeIf { it.isNotEmpty() }
?.let { authorities ->
append("Authorities: ${authorities.joinToString(", ")}\n")
append(params.triggeredContentUris.joinToString("\n"))
} ?: append("(No content)")
Log.i(TAG, toString())
}
return Result.success()
}
}
在系統限制下測試應用程式
對應用程式進行最佳化調整,在記憶體不足或記憶體不足的情況下執行。 都有助於改善效能和使用者體驗移除背景依附元件 以及已註冊資訊清單的隱式廣播接收器, 這類裝置上的運作效能更好建議您在執行期間最佳化應用程式 完全不必使用這些背景程序
還有一些其他 Android Debug Bridge (ADB) 指令可協助您測試應用程式 停用這些背景程序的行為:
模擬隱式廣播和背景服務 無法使用,請輸入下列指令:
$ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND ignore
如要重新啟用隱式廣播和背景服務,請輸入以下內容 指令:
$ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND allow
進一步最佳化應用程式
如要瞭解其他改善背景任務的好方法行為,請參閱 最佳化任務排程 API 的電池用量 說明文件。