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

如何使用WorkManager实现应用关闭时运行后台服务?

解决WorkManager PeriodicWorkRequest在应用关闭后停止运行的问题

看起来你遇到的核心问题是Worker在异步操作完成前就被系统回收了,再加上部分厂商系统的电池优化限制,导致应用关闭后下载任务中断。下面一步步给你解决思路和代码修改方案:

1. 修复Worker的异步操作问题(最关键)

你的doWork()方法里启动AndroidNetworking的异步下载后,立刻返回了WorkerResult.SUCCESS——这会让WorkManager认为任务已经完成,直接回收Worker实例。一旦应用被关闭,这个Worker进程就会被系统杀掉,下载自然就停了。

解决方法是用CountDownLatch阻塞doWork()方法,直到异步下载完成或出错再返回结果:

@Override
public WorkerResult doWork() {
    context = getApplicationContext();
    Data data = getInputData();
    String url = data.getString("url", "");
    
    String mainName = "renaldi";
    String mimeType = url.substring(url.length()-4);
    String namePath = mainName + "Files-"+changeFormat(new Date())+mimeType;
    
    notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    createNotification();
    AndroidNetworking.initialize(context);

    // 用CountDownLatch等待异步操作完成
    final CountDownLatch latch = new CountDownLatch(1);
    final WorkerResult[] taskResult = {WorkerResult.SUCCESS};

    AndroidNetworking.download(url, context.getExternalFilesDir(DIRECTORY_DOWNLOADS)+"/video/" , namePath)
        .setTag("download")
        .setPriority(Priority.HIGH)
        .build()
        .setDownloadProgressListener(new DownloadProgressListener() {
            @Override
            public void onProgress(long bytesDownloaded, long totalBytes) {
                final int dl_progress = (int) ((bytesDownloaded * 100l) / totalBytes);
                updateNotification(dl_progress);
            }
        })
        .startDownload(new DownloadListener() {
            @Override
            public void onDownloadComplete() {
                onDownloadCompleted();
                latch.countDown(); // 下载完成,释放 latch
            }
            @Override
            public void onError(ANError error) {
                taskResult[0] = WorkerResult.FAILURE; // 标记任务失败
                latch.countDown();
            }
        });

    try {
        latch.await(); // 阻塞当前线程,直到下载完成
    } catch (InterruptedException e) {
        e.printStackTrace();
        taskResult[0] = WorkerResult.RETRY; // 中断时标记重试
    }

    return taskResult[0];
}

2. 处理系统电池优化限制

国内很多厂商(小米、华为、OPPO等)的定制系统有严格的后台管控,即使WorkManager设计为后台运行,也可能被电池优化策略拦截。

方案一:引导用户手动关闭电池优化

你可以在应用设置里添加一个入口,引导用户关闭当前应用的电池优化:

// 检查是否已获得电池优化豁免权
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
boolean isIgnored = powerManager.isIgnoringBatteryOptimizations(context.getPackageName());
if (!isIgnored) {
    Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
    intent.setData(Uri.parse("package:" + context.getPackageName()));
    // 注意:要在Activity中启动这个Intent,不能在Worker里直接启动
    startActivity(intent);
}

同时需要在AndroidManifest.xml中添加权限:

<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />

方案二:申请后台运行权限

对于Android 10及以上版本,你还可以申请后台运行权限,但这个权限需要向用户说明用途,否则容易被拒绝。在AndroidManifest.xml中添加:

<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

3. 优化WorkManager配置与初始化

  • 建议在Application类中初始化AndroidNetworking,避免在每个Worker实例中重复初始化:
public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        AndroidNetworking.initialize(this);
    }
}

然后在AndroidManifest.xml中注册这个Application类:

<application
    android:name=".MyApplication"
    ...>
    <!-- 其他配置 -->
</application>
  • 你的PeriodicWorkRequest周期设置为12小时是符合要求的(WorkManager要求周期最短15分钟),无需调整,但要注意系统会根据负载情况弹性调整执行时间,不是严格准时触发。

4. 验证任务状态

你可以通过WorkManager的getWorkInfoByIdLiveData方法监听任务状态,确认任务是否在后台正常运行:

WorkManager.getInstance(context)
    .getWorkInfoByIdLiveData(request.getId())
    .observe(this, workInfo -> {
        if (workInfo != null) {
            WorkInfo.State state = workInfo.getState();
            Log.d("WorkManager", "任务状态:" + state.name());
        }
    });

这样修改后,你的PeriodicWorkRequest就能在应用关闭后继续执行下载任务了,只要系统没有强制杀掉进程且网络条件满足。

内容的提问来源于stack exchange,提问作者Renaldi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:58:43