You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

API 31下如何在后台延迟启动长时任务?

API 31+ 后台延迟启动长时任务的解决方案

问题背景

在API 31之前,我们通常通过WorkManager设置初始延迟,结合Worker内启动前台服务的方式,实现用户退出应用时延迟触发长时任务。但Android 12(API 31)新增后台启动前台服务的限制,直接在后台启动前台服务会抛出ForegroundServiceStartNotAllowedException。尝试用setExpedited替代时,又会因「加急任务不能设置延迟」触发java.lang.IllegalArgumentException: Expedited jobs cannot be delayed报错。

解决方案:拆分任务流程

核心思路是把「延迟等待」和「执行长时任务」拆分为两个独立的Work任务:

  1. 第一个普通Work仅负责延迟等待,不加急,到点后触发第二个任务
  2. 第二个任务使用setExpedited标记为加急任务,执行真正的长时操作(此时系统允许后台启动前台服务)

代码实现

  1. 延迟触发Worker:仅负责到点后启动长时任务
public class DelayTriggerWorker extends Worker {
    public DelayTriggerWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        // 创建并执行加急的长时任务
        OneTimeWorkRequest longRunningWork = new OneTimeWorkRequest.Builder(CloudWorker.class)
                .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
                .build();
        WorkManager.getInstance(getApplicationContext()).enqueue(longRunningWork);
        return Result.success();
    }
}
  1. 修改启动逻辑:启动延迟触发任务,而非直接启动长时任务
public static void startCloudWorker() {
    // 设置需要的延迟时间,这里以5分钟为例
    OneTimeWorkRequest delayRequest = new OneTimeWorkRequest.Builder(DelayTriggerWorker.class)
            .setInitialDelay(5, TimeUnit.MINUTES)
            .build();
    WorkManager.getInstance(getApplicationContext()).enqueue(delayRequest);
}
  1. 保留原长时任务Worker:无需修改,正常处理前台服务和业务逻辑
public class CloudWorker extends Worker {
    public CloudWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        final ForegroundInfo foregroundInfo = createForegroundInfo(...);
        setForegroundAsync(foregroundInfo);
        
        // 执行你的长时业务逻辑
        
        return Result.success();
    }
}

关键注意事项

  • 权限要求:Android 13及以上需申请POST_NOTIFICATIONS权限,否则前台服务通知无法显示,任务可能被系统终止
  • 配额处理:OutOfQuotaPolicy参数需根据业务选择:
    • RUN_AS_NON_EXPEDITED_WORK_REQUEST:配额不足时转为普通任务(可能延迟执行)
    • DROP_WORK_REQUEST:配额不足时直接丢弃任务
  • 延迟准确性:WorkManager的延迟为近似值,系统会根据电池优化、系统负载等情况调整实际触发时间

内容的提问来源于stack exchange,提问作者Cheok Yan Cheng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 05:45:32