Quando utilizzi una Worker
, WorkManager
chiama automaticamente Worker.doWork()
in un thread in background. Il thread in background proviene da Executor
specificato in Configuration
di WorkManager.
Per impostazione predefinita, WorkManager configura un Executor
per te, ma puoi anche personalizzarlo
la tua. Ad esempio, puoi condividere un esecutore in background esistente
crea un Executor
a thread unico per assicurarti che tutto il lavoro in background
vengono eseguiti in sequenza o anche specificare un Executor
personalizzato. Per personalizzare
Executor
, assicurati di inizializzare WorkManager manualmente.
Quando configuri WorkManager manualmente, puoi specificare Executor
come
che 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 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()
è un
sincrona: devi svolgere interamente il lavoro in background
in modo da bloccarlo e terminarlo nel momento in cui il metodo viene chiuso. Se chiami
l'API asincrona in doWork()
e restituisce un valore Result
, il callback potrebbe non
funzionino correttamente. Se ti trovi in questa situazione, potresti utilizzare un ListenableWorker
(vedi Threading in ListenableWorker).
Quando un Worker
attualmente in esecuzione viene interrotto per qualsiasi motivo,
riceve una chiamata al numero Worker.onStopped()
. Esegui l'override di questo metodo o
chiama Worker.isStopped()
per controllare il codice e liberare risorse quando necessario. Quando Worker
nell'esempio precedente è arrestata, potrebbe trovarsi nel mezzo del suo loop di
scaricare elementi e continuerà a farlo anche se l'operazione è stata interrotta. A
per ottimizzare questo comportamento, puoi procedere in questo 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 un Worker
, non importa da cosa torni
Worker.doWork()
; Result
verrà ignorato.