Когда вы используете 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
будет проигнорирован.