Когда вы используете Worker
, WorkManager автоматически вызывает Worker.doWork()
в фоновом потоке. Фоновый поток исходит от Executor
, указанного в Configuration
WorkManager. По умолчанию WorkManager настраивает для вас Executor
, но вы также можете настроить свой собственный. Например, вы можете поделиться существующим фоновым Executor в своем приложении, создать однопоточный Executor
, чтобы обеспечить последовательное выполнение всей фоновой работы, или даже указать собственный Executor
. Чтобы настроить Executor
, обязательно инициализируйте WorkManager вручную.
При настройке WorkManager вручную вы можете указать Executor
следующим образом:
Котлин
WorkManager.initialize( context, Configuration.Builder() // Uses a fixed thread pool of size 8 threads. .setExecutor(Executors.newFixedThreadPool(8)) .build())
Ява
WorkManager.initialize( context, new Configuration.Builder() .setExecutor(Executors.newFixedThreadPool(8)) .build());
Вот пример простого Worker
, который загружает содержимое веб-страницы 100 раз:
Котлин
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() } }
Ява
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()
— это синхронный вызов: ожидается, что вы выполните всю фоновую работу в режиме блокировки и завершите ее к моменту выхода из метода. Если вы вызываете асинхронный API в doWork()
и возвращаете Result
, ваш обратный вызов может работать неправильно. Если вы оказались в такой ситуации, рассмотрите возможность использования ListenableWorker
(см. Потоки в ListenableWorker ).
Когда работающий в данный момент Worker
останавливается по какой-либо причине , он получает вызов Worker.onStopped()
. Переопределите этот метод или вызовите Worker.isStopped()
, чтобы проверить код и при необходимости освободить ресурсы. Когда Worker
в приведенном выше примере остановлен, он может находиться в середине цикла загрузки элементов и продолжит это делать, даже если он был остановлен. Чтобы оптимизировать это поведение, вы можете сделать что-то вроде этого:
Котлин
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() } }
Ява
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
будет проигнорирован.