Dans certains cas, vous devrez peut-être fournir une stratégie de thread personnalisée. Pour
exemple, vous devrez peut-être gérer une opération asynchrone basée sur le rappel.
WorkManager prend en charge ce cas d'utilisation avec
ListenableWorker
ListenableWorker est l'API de nœud de calcul la plus basique ;
Worker,
CoroutineWorker
RxWorker sont tous dérivés de cette classe. A
ListenableWorker ne signale que le début et la fin de la tâche, et quand elle doit partir.
entièrement à vous. Le signal de début des tâches est appelé
Il est donc très important que vous accédiez à un thread d'arrière-plan
manuellement.
La méthode abstraite
ListenableWorker.startWork()
renvoie un ListenableFuture des
Result A
ListenableFuture est une interface légère: il s'agit d'un Future qui fournit
une fonctionnalité permettant d'associer des écouteurs et de propager des exceptions. Dans
startWork, vous devez renvoyer un ListenableFuture, que vous
est défini avec le Result de l'opération une fois celle-ci terminée. Vous pouvez créer
ListenableFuture de l'une des deux manières suivantes:
- Si vous employez Guava, utilisez
ListeningExecutorService. - Sinon, incluez
councurrent-futuresdans votre fichier Gradle et utilisezCallbackToFutureAdapter
Si vous souhaitez exécuter une tâche basée sur un rappel asynchrone, vous devez faites quelque chose comme ceci:
Kotlin
class CallbackWorker( context: Context, params: WorkerParameters ) : ListenableWorker(context, params) { override fun startWork(): ListenableFuture<Result> { return CallbackToFutureAdapter.getFuture { completer -> val callback = object : Callback { var successes = 0 override fun onFailure(call: Call, e: IOException) { completer.setException(e) } override fun onResponse(call: Call, response: Response) { successes++ if (successes == 100) { completer.set(Result.success()) } } } repeat(100) { downloadAsynchronously("https://example.com", callback) } callback } } }
Java
public class CallbackWorker extends ListenableWorker { public CallbackWorker(Context context, WorkerParameters params) { super(context, params); } @NonNull @Override public ListenableFuture<Result> startWork() { return CallbackToFutureAdapter.getFuture(completer -> { Callback callback = new Callback() { int successes = 0; @Override public void onFailure(Call call, IOException e) { completer.setException(e); } @Override public void onResponse(Call call, Response response) { successes++; if (successes == 100) { completer.set(Result.success()); } } }; for (int i = 0; i < 100; i++) { downloadAsynchronously("https://www.example.com", callback); } return callback; }); } }
Que se passe-t-il si votre travail est
arrêté ?
Le ListenableFuture d'un ListenableWorker est toujours annulé lorsque la tâche est
s'arrêtera. Avec un CallbackToFutureAdapter, il vous suffit d'ajouter un
d'annulation, comme suit:
Kotlin
class CallbackWorker( context: Context, params: WorkerParameters ) : ListenableWorker(context, params) { override fun startWork(): ListenableFuture<Result> { return CallbackToFutureAdapter.getFuture { completer -> val callback = object : Callback { var successes = 0 override fun onFailure(call: Call, e: IOException) { completer.setException(e) } override fun onResponse(call: Call, response: Response) { ++successes if (successes == 100) { completer.set(Result.success()) } } } completer.addCancellationListener(cancelDownloadsRunnable, executor) repeat(100) { downloadAsynchronously("https://example.com", callback) } callback } } }
Java
public class CallbackWorker extends ListenableWorker { public CallbackWorker(Context context, WorkerParameters params) { super(context, params); } @NonNull @Override public ListenableFuture<Result> startWork() { return CallbackToFutureAdapter.getFuture(completer -> { Callback callback = new Callback() { int successes = 0; @Override public void onFailure(Call call, IOException e) { completer.setException(e); } @Override public void onResponse(Call call, Response response) { ++successes; if (successes == 100) { completer.set(Result.success()); } } }; completer.addCancellationListener(cancelDownloadsRunnable, executor); for (int i = 0; i < 100; ++i) { downloadAsynchronously("https://www.example.com", callback); } return callback; }); } }
Exécuter un ListenableWorker dans un processus différent
Vous pouvez également lier un nœud de calcul à un processus spécifique à l'aide de RemoteListenableWorker, une implémentation de ListenableWorker.
RemoteListenableWorker se lie à un processus spécifique avec deux arguments supplémentaires que vous fournissez dans les données d'entrée lors de la création de la requête de tâche : ARGUMENT_CLASS_NAME et ARGUMENT_PACKAGE_NAME.
L'exemple suivant illustre la création d'une requête de tâche liée à un processus spécifique :
Kotlin
val PACKAGE_NAME = "com.example.background.multiprocess" val serviceName = RemoteWorkerService::class.java.name val componentName = ComponentName(PACKAGE_NAME, serviceName) val data: Data = Data.Builder() .putString(ARGUMENT_PACKAGE_NAME, componentName.packageName) .putString(ARGUMENT_CLASS_NAME, componentName.className) .build() return OneTimeWorkRequest.Builder(ExampleRemoteListenableWorker::class.java) .setInputData(data) .build()
Java
String PACKAGE_NAME = "com.example.background.multiprocess"; String serviceName = RemoteWorkerService.class.getName(); ComponentName componentName = new ComponentName(PACKAGE_NAME, serviceName); Data data = new Data.Builder() .putString(ARGUMENT_PACKAGE_NAME, componentName.getPackageName()) .putString(ARGUMENT_CLASS_NAME, componentName.getClassName()) .build(); return new OneTimeWorkRequest.Builder(ExampleRemoteListenableWorker.class) .setInputData(data) .build();
Pour chaque RemoteWorkerService, vous devez également ajouter une définition de service dans votre fichier AndroidManifest.xml :
<manifest ... > <service android:name="androidx.work.multiprocess.RemoteWorkerService" android:exported="false" android:process=":worker1" /> <service android:name=".RemoteWorkerService2" android:exported="false" android:process=":worker2" /> ... </manifest>