在工作器中进行线程处理

当您使用 Worker 时,WorkManager 会自动在后台线程中调用 Worker.doWork()。该后台线程来自于 WorkManager 的 Configuration 中指定的 Executor。默认情况下,WorkManager 会为您设置 Executor,但您也可以自己进行自定义。例如,您可以在应用中共享现有的后台 Executor,也可以创建单线程 Executor 以确保所有后台工作都按顺序执行,甚至可以指定一个自定义 Executor。如需自定义 Executor,请确保手动初始化 WorkManager。

在手动配置 WorkManager 时,您可以按以下方式指定 Executor

Kotlin

WorkManager.initialize(
    context,
    Configuration.Builder()
         // Uses a fixed thread pool of size 8 threads.
        .setExecutor(Executors.newFixedThreadPool(8))
        .build())

Java

WorkManager.initialize(
    context,
    new Configuration.Builder()
        .setExecutor(Executors.newFixedThreadPool(8))
        .build());

下面是一个简单的 Worker 示例,其会下载网页内容 100 次:

Kotlin

class DownloadWorker(context: Context, params: WorkerParameters) : Worker(context, params) {

    override fun doWork(): ListenableWorker.Result {
        repeat(100) {
            try {
                downloadSynchronously("https://www.google.com")
            } catch (e: IOException) {
                return ListenableWorker.Result.failure()
            }
        }

        return ListenableWorker.Result.success()
    }
}

Java

public class DownloadWorker extends Worker {

    public DownloadWorker(Context context, WorkerParameters params) {
        super(context, params);
    }

    @NonNull
    @Override
    public Result doWork() {
        for (int i = 0; i < 100; i++) {
            try {
                downloadSynchronously("https://www.google.com");
            } catch (IOException e) {
                return Result.failure();
            }
        }

        return Result.success();
    }

}

请注意,Worker.doWork() 是同步调用 - 您应以阻塞方式完成整个后台工作,并在方法退出时完成工作。如果您在 doWork() 中调用异步 API 并返回 Result,那么回调可能无法正常运行。如果您遇到这种情况,请考虑使用 ListenableWorker(请参阅在 ListenableWorker 中进行线程处理)。

如果当前正在运行的 Worker 因任何原因而停止,它就会收到对 Worker.onStopped() 的调用。在必要的情况下,只需替换此方法或调用 Worker.isStopped(),即可对代码进行检查点处理并释放资源。当上述示例中的 Worker 被停止时,内容的下载可能才完成了一半;但即使该工作器被停止,下载也会继续。如需优化此行为,您可以执行以下操作:

Kotlin

class DownloadWorker(context: Context, params: WorkerParameters) : Worker(context, params) {

    override fun doWork(): ListenableWorker.Result {
        repeat(100) {
            if (isStopped) {
                break
            }

            try {
                downloadSynchronously("https://www.google.com")
            } catch (e: IOException) {
                return ListenableWorker.Result.failure()
            }

        }

        return ListenableWorker.Result.success()
    }
}

Java

public class DownloadWorker extends Worker {

    public DownloadWorker(Context context, WorkerParameters params) {
        super(context, params);
    }

    @NonNull
    @Override
    public Result doWork() {
        for (int i = 0; i < 100; ++i) {
            if (isStopped()) {
                break;
            }

            try {
                downloadSynchronously("https://www.google.com");
            } catch (IOException e) {
                return Result.failure();
            }
        }

        return Result.success();
    }
}

Worker 停止后,从 Worker.doWork() 返回什么已不重要;Result 将被忽略。