При использовании Worker WorkManager автоматически вызывает Worker.doWork() в фоновом потоке. Фоновый поток поступает из Executor, указанного в Configuration WorkManager.
По умолчанию 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() – это синхронный вызов. Вам нужно выполнить всю фоновую работу в блокирующем режиме и завершить ее к моменту выхода из метода. Если вы вызываете асинхронный API в doWork() и возвращаете 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 будет игнорироваться.