Worker 中的多线程

当您使用 Worker 时,WorkManager 会自动在后台线程上调用 Worker.doWork()。后台线程来自 WorkManager 的 Configuration 中指定的 Executor。默认情况下,WorkManager 会为您设置一个 Executor,但您也可以自定义自己的 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 将被忽略。