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-futures
in 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>