Cuando usas un Worker
, WorkManager llama automáticamente a Worker.doWork()
en un subproceso, en segundo plano. El subproceso en segundo plano proviene del Executor
que se especificó en Configuration
de WorkManager.
De forma predeterminada, WorkManager configura un Executor
por ti, pero también puedes personalizar el tuyo. Por ejemplo, puedes compartir un ejecutor existente en segundo plano en la app, crear un Executor
de un solo subproceso para asegurarte de que todas las tareas en segundo plano se ejecuten de forma secuencial, o incluso especificar un Executor
personalizado. Para personalizar el Executor
, asegúrate de iniciar WorkManager de forma manual.
Cuando configuras WorkManager manualmente, puedes especificar tu Executor
de la siguiente manera:
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());
A continuación, se muestra un ejemplo de un Worker
simple que descarga el contenido de una página web 100 veces:
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(); } }
Ten en cuenta que Worker.doWork()
es una llamada síncrona; se espera que hagas todas las tareas en segundo plano de forma bloqueada y que finalices cuando el método se cierre. Si llamas a una API asíncrona en doWork()
y muestras un Result
, es posible que la devolución de llamada no funcione correctamente. Si te encuentras con esta situación, considera usar un ListenableWorker
(consulta Cómo ejecutar subprocesos en ListenableWorker).
Cuando un Worker
que está en ejecución se detiene por algún motivo, recibe una llamada a Worker.onStopped()
. Anula este método o llama a Worker.isStopped()
para establecer un punto de control de tu código y liberar recursos según sea necesario. Cuando se detiene Worker
en el ejemplo anterior, puede estar en el medio de su bucle de descarga de elementos y continuará haciéndolo aunque se haya detenido. Para optimizar este comportamiento, puedes hacer lo siguiente:
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(); } }
Una vez que se detiene un Worker
, no importa lo que muestres de Worker.doWork()
; el Result
se ignorará.