Quando utilizzi una Worker
, WorkManager
chiama automaticamente Worker.doWork()
in un thread in background. Il thread in background proviene dall'elemento Executor
specificato in Configuration
di WorkManager.
Per impostazione predefinita, WorkManager configura un Executor
per te, ma puoi anche personalizzare
il tuo. Ad esempio, puoi condividere un esecutore in background esistente nella tua
app, creare un Executor
con thread singolo per assicurarti che tutto il lavoro in background venga eseguito
in sequenza o persino specificare un Executor
personalizzato. Per personalizzare Executor
, assicurati di inizializzare WorkManager manualmente.
Quando configuri WorkManager manualmente, puoi specificare Executor
come segue:
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());
Ecco un esempio di un Worker
semplice che scarica i contenuti di una pagina web 100 volte:
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(); } }
Tieni presente che Worker.doWork()
è una chiamata sincrona: devi completare l'intera operazione in background in modo da bloccare e completarla entro il momento in cui il metodo viene eliminato. Se chiami
un'API asincrona in doWork()
e restituisci un Result
, il callback potrebbe
non funzionare correttamente. Se ti trovi in questa situazione, valuta la possibilità di utilizzare una ListenableWorker
(vedi Threading inListenableWorker).
Quando un dispositivo Worker
attualmente in esecuzione viene bloccato per qualsiasi motivo, riceve una chiamata a Worker.onStopped()
. Esegui l'override di questo metodo o chiama Worker.isStopped()
per eseguire un checkpoint del codice e liberare risorse se necessario. Quando Worker
nell'esempio precedente viene interrotto, potrebbe trovarsi nel bel mezzo del suo loop di
download di elementi e continuerà a farlo anche se è stato interrotto. Per ottimizzare questo comportamento, puoi procedere nel seguente modo:
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 volta interrotto Worker
, non importa cosa torni da Worker.doWork()
; il Result
verrà ignorato.