Android 12中setExpedited能否替代前台服务执行后台长任务?
Android 12后台长时间任务适配疑问解答
背景说明
从Android 12(API级别31)开始,目标版本为该级别及以上的应用在后台运行时,除少数特殊情况外无法启动前台服务。
业务场景
在Android 12之前,当应用在onPause(LifecycleOwner owner)回调触发进入后台时,会通过前台服务执行长时间云同步任务:具体是在CloudWorker的doWork()方法中调用setForegroundAsync(foregroundInfo),以此提升进程优先级,避免被系统杀死。
Google在Android 12中推荐使用setExpedited替代原有方案,示例代码如下:
OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(CloudWorkerV31.class) .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST) .addTag(CloudWorkerV31.TAG) .build();
疑问解答
1. setExpedited的底层机制与普通Work任务有何不同?
- 优先级差异:加急任务会被系统优先调度,分配更高的进程优先级,远高于普通后台Work任务,大幅降低被系统回收的概率
- 资源保障:加急任务享有类似前台服务的资源分配优先级,系统会尽量为其保留运行资源;普通Work任务属于低优先级后台任务,资源受限,容易在系统资源紧张时被终止
- 配额限制:系统对每日可执行的加急任务数量有配额限制,当超出配额时,会按照指定策略(示例中的
RUN_AS_NON_EXPEDITED_WORK_REQUEST)降级为普通任务执行 - 通知要求:加急任务默认会在状态栏显示通知,告知用户有后台任务在执行;普通Work任务无强制通知要求
2. 它能否实现应用进入后台时执行长时间任务的需求?
- 大部分场景可以满足:如果任务在系统加急配额范围内,加急任务能获得足够的进程优先级保障,大概率可以完成长时间云同步;但如果超出配额,任务会降级为普通后台任务,此时系统可能在资源紧张时终止任务
- 优化建议:可以将长时间任务拆分为多个小任务链式执行,或者通过
WorkRequest.Builder.setConstraints()设置网络、充电等约束,确保任务在系统资源充足的时机执行
补充:正常情况下后台应用是否无法再启动长时间任务?
并非完全无法执行。只是不能再通过随意启动前台服务的方式保障任务运行。通过setExpedited的加急任务、结合合理的任务拆分和约束配置,大部分长时间同步场景可以覆盖;如果是必须100%保证完成的任务,可尝试利用系统允许后台启动前台服务的特殊场景(比如用户最近与应用有交互、应用存在高优先级通知等)。
内容的提问来源于stack exchange,提问作者Cheok Yan Cheng
相关产品推荐
相关产品推荐

