后台进程可能会耗费大量内存和电池电量。例如, 隐式广播可能会启动许多已注册到 并监听,即使这些进程可能没有很多工作。这种类型 对设备性能和用户体验产生重大影响。
为避免受到系统限制,请确保使用正确的 API, 后台任务。通过 后台任务概览文档可帮助您 找到适合您需求的 API。
用户发起的限制
如果应用出现 Android Vitals 中所述的一些不良行为, 系统会提示用户限制该应用对系统资源的访问权限。
如果系统发现应用消耗的资源过多,则会通知 用户,并为用户提供限制应用操作的选项。 可触发此类通知的行为包括:
- 唤醒锁定次数过多:屏幕处于以下状态时,1 次部分唤醒锁定会保持 1 小时 停用
- 后台服务过多:如果应用以低于 26 的 API 级别为目标平台 并且包含过多的后台服务
施加的确切限制由设备制造商决定。对于 例如,在 AOSP build 中,受限应用无法运行作业、触发警报或使用 除非应用在前台运行。
对接收网络活动广播的限制
应用不会收到 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 调试桥 (ADB) 命令可以帮助您测试应用 停用这些后台进程时的行为:
为了模拟隐式广播和后台服务 找不到,请输入以下命令:
$ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND ignore
要重新启用隐式广播和后台服务,请输入以下内容 命令:
$ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND allow
进一步优化应用
如需了解优化后台任务的其他有效方法行为,请参见 优化任务调度 API 的电池使用情况 文档。