In bestimmten Situationen müssen Sie möglicherweise eine benutzerdefinierte Threading-Strategie bereitstellen. Für
müssen Sie möglicherweise einen auf einem Rückruf basierenden asynchronen Vorgang abwickeln.
WorkManager unterstützt diesen Anwendungsfall mit
ListenableWorker
ListenableWorker ist die einfachste Worker-API.
Worker,
CoroutineWorker und
Die RxWorker-Elemente stammen alle aus dieser Klasse. A
Mit ListenableWorker wird nur signalisiert, wann die Arbeit beginnen und anhalten soll und wann sie verlassen werden soll
ganz Ihnen überlassen. Das Signal „Arbeit starten“ wird auf der
Es ist also sehr wichtig, dass Sie sich im Hintergrund Ihres Threads
eine manuelle Auswahl treffen.
Die abstrakte Methode
ListenableWorker.startWork()
gibt ListenableFuture des Werts
Result A
ListenableFuture ist eine schlanke Oberfläche: Es ist eine Future, die
zum Anhängen von Listenern und Übertragen von Ausnahmen. Im
startWork-Methode verwenden, wird erwartet, dass Sie eine ListenableFuture zurückgeben,
wird nach Abschluss mit dem Result des Vorgangs festgelegt. Sie können
ListenableFuture-Instanzen auf eine der beiden folgenden Arten:
- Wenn Sie Guava verwenden, verwenden Sie
ListeningExecutorService. - Andernfalls fügen Sie
councurrent-futuresin der Gradle-Datei ein und verwendenCallbackToFutureAdapter
Wenn Sie einige Arbeit basierend auf einem asynchronen Callback ausführen wollten, würden Sie Gehen Sie in etwa so vor:
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; }); } }
Was passiert, wenn Ihre Arbeit
angehalten?
Die ListenableFuture einer ListenableWorker wird immer abgebrochen, wenn die Arbeit
voraussichtlich beendet wird. Mit einem CallbackToFutureAdapter müssen Sie einfach ein
Kündigungs-Listener:
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; }); } }
ListenableWorker in einem anderen Prozess ausführen
Sie können einen Worker auch mit
RemoteListenableWorker,
eine Implementierung von ListenableWorker.
RemoteListenableWorker bindet mit zwei zusätzlichen Argumenten an einen bestimmten Prozess.
die Sie als Teil der Eingabedaten beim Erstellen der Arbeitsanfrage bereitstellen:
ARGUMENT_CLASS_NAME und ARGUMENT_PACKAGE_NAME.
Im folgenden Beispiel sehen Sie, wie eine Arbeitsanfrage erstellt wird, die an eine bestimmten Prozess:
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();
Für jede RemoteWorkerService müssen Sie auch eine Dienstdefinition in
Ihre AndroidManifest.xml-Datei:
<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>