在工作器中进行线程处理

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

Kotlin

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

Java

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

下面是一个简单的工作器示例,它按顺序下载某些网站的内容:

Kotlin

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

        override fun doWork(): ListenableWorker.Result {
            for (i in 0..99) {
                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 {
            for (i in 0..99) {
                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 将被忽略。