Mit WorkManager können Sie ein WorkRequest
aktualisieren, nachdem Sie es bereits in die Warteschlange gestellt haben. Dies ist oft bei größeren Anwendungen erforderlich, in denen Einschränkungen häufig geändert werden oder die Worker spontan aktualisiert werden müssen. Ab WorkManager Version 2.8.0 wird die updateWork()
API verwendet.
Mit der Methode updateWork()
können Sie bestimmte Aspekte einer WorkRequest
im laufenden Betrieb ändern, ohne dass Sie eine neue Anfrage manuell abbrechen und in die Warteschlange stellen müssen. Dies vereinfacht den Entwicklungsprozess erheblich.
Aufgaben nicht abbrechen
Im Allgemeinen sollten Sie es vermeiden, eine vorhandene WorkRequest abzubrechen und eine neue in die Warteschlange zu stellen. Dies kann dazu führen, dass die Anwendung bestimmte Aufgaben wiederholt, und Sie müssen möglicherweise eine beträchtliche Menge an zusätzlichem Code schreiben.
Die folgenden Beispiele zeigen, wo das Abbrechen einer WorkRequest Probleme verursachen kann:
- Backend-Anfrage: Wenn Sie eine
Worker
abbrechen, während eine Nutzlast zum Senden an den Server berechnet wird, muss der neueWorker
von vorn beginnen und die potenziell teure Nutzlast neu berechnen. - Planung:Wenn Sie eine
PeriodicWorkRequest
abbrechen und die neuePeriodicWorkRequest
nach demselben Zeitplan ausgeführt werden soll, müssen Sie eine Zeitverschiebung berechnen, damit die neue Ausführungszeit mit der vorherigen Arbeitsanfrage übereinstimmt.
Mit der updateWork()
API können Sie die Einschränkungen einer Arbeitsanfrage und andere Parameter aktualisieren, ohne die Anfrage abbrechen und eine neue in die Warteschlange stellen zu müssen.
Wann Sie die Arbeit abbrechen sollten
Es gibt Fälle, in denen Sie WorkRequest
direkt abbrechen sollten, anstatt updateWork()
aufzurufen. Dies sollten Sie tun, wenn Sie den grundlegenden Charakter der Arbeit, die Sie in die Warteschlange gestellt haben, ändern möchten.
Wann die Arbeitsadresse aktualisiert werden sollte
Stellen Sie sich eine Foto-App vor, mit der täglich die Fotos des Nutzers gesichert werden. Dafür wurde ein PeriodicWorkRequest
in die Warteschlange gestellt. WorkRequest
hat Einschränkungen, die es erforderlich machen, dass das Gerät aufgeladen wird und mit dem WLAN verbunden ist.
Allerdings lädt der Nutzer sein Gerät mit einem Schnellladegerät nur 20 Minuten pro Tag auf. In diesem Fall kann die App WorkRequest
aktualisieren, um die Ladebeschränkung zu lockern. So können die Fotos auch dann hochgeladen werden, wenn das Gerät nicht vollständig geladen ist.
In diesem Fall können Sie mit der Methode updateWork()
die Einschränkungen der Arbeitsanfrage aktualisieren.
Aufgaben aktualisieren
Die Methode updateWork()
bietet eine einfache Möglichkeit zum Aktualisieren einer vorhandenen WorkRequest
, ohne dass eine neue abgebrochen und in die Warteschlange gestellt werden muss.
So verwenden Sie die Aktualisierung von Aufgaben in der Warteschlange:
- Vorhandene ID für Aufgaben in der Warteschlange abrufen: Rufen Sie die ID der WorkRequest ab, die Sie aktualisieren möchten. Sie können diese ID mit einer der
getWorkInfo
APIs abrufen oder die ID aus der ursprünglichen WorkRequest manuell speichern, um sie später in der öffentlichen PropertyWorkRequest.id
abzurufen, bevor sie in die Warteschlange gestellt wird. - Create new WorkRequest: Erstellen Sie eine neue
WorkRequest
und verwenden SieWorkRequest.Builder.setID()
, um die ID entsprechend der vorhandenenWorkRequest
festzulegen. - Einschränkungen festlegen: Verwenden Sie
WorkRequest.Builder.setConstraints()
, um die neuen WorkManager-Einschränkungen zu übergeben. - UpdateWork aufrufen: Übergib die neue WorkRequest an
updateWork()
.
Arbeitsbeispiel aktualisieren
Das folgende Beispiel-Code-Snippet in Kotlin zeigt, wie mit der Methode updateWork()
die Akkubeschränkungen einer WorkRequest
geändert werden können, die zum Hochladen von Fotos verwendet wird:
suspend fun updatePhotoUploadWork() {
// Get instance of WorkManager.
val workManager = WorkManager.getInstance(context)
// Retrieve the work request ID. In this example, the work being updated is unique
// work so we can retrieve the ID using the unique work name.
val photoUploadWorkInfoList = workManager.getWorkInfosForUniqueWork(
PHOTO_UPLOAD_WORK_NAME
).await()
val existingWorkRequestId = photoUploadWorkInfoList.firstOrNull()?.id ?: return
// Update the constraints of the WorkRequest to not require a charging device.
val newConstraints = Constraints.Builder()
// Add other constraints as required here.
.setRequiresCharging(false)
.build()
// Create new WorkRequest from existing Worker, new constraints, and the id of the old WorkRequest.
val updatedWorkRequest: WorkRequest =
OneTimeWorkRequestBuilder<MyWorker>()
.setConstraints(newConstraints)
.setId(existingWorkRequestId)
.build()
// Pass the new WorkRequest to updateWork().
workManager.updateWork(updatedWorkRequest)
}
Ergebnis verarbeiten
updateWork()
gibt ein ListenableFuture<UpdateResult>
zurück. Die angegebene UpdateResult
kann einen der verschiedenen Werte enthalten, die angeben, ob WorkManager Ihre Änderungen anwenden konnte. Es zeigt auch an, wann die
Änderung übernommen wurde.
Weitere Informationen finden Sie in der Referenz zu updateWork()
und UpdateResult
in der Referenz.
Arbeit mit Generationen im Blick behalten
Jedes Mal, wenn Sie eine WorkRequest
aktualisieren, erhöht sich die generation um eins. So können Sie genau verfolgen, welche WorkRequest
derzeit in die Warteschlange eingereiht wird.
Generierungen bieten Ihnen mehr Kontrolle beim Beobachten, Tracing und Testen von Arbeitsanfragen.
So rufen Sie die Generierung eines WorkRequest
ab:
- WorkInfo: Rufen Sie
WorkManager.getWorkInfoById()
auf, um eine Instanz vonWorkInfo
abzurufen, die IhremWorkRequest
entspricht.- Sie können eine von mehreren Methoden aufrufen, die ein
WorkInfo
zurückgeben. Weitere Informationen finden Sie in der WorkManager-Referenz.
- Sie können eine von mehreren Methoden aufrufen, die ein
- getGeneration: Rufen Sie
getGeneration()
für die Instanz vonWorkInfo
auf. Der zurückgegebeneInt
entspricht der Generation desWorkRequest
.- Es gibt kein Feld und keine Eigenschaft für die Generierung, sondern nur die Methode
WorkInfo.getGeneration()
.
- Es gibt kein Feld und keine Eigenschaft für die Generierung, sondern nur die Methode
Beispiel für Track-Generierung
Im Folgenden finden Sie eine Beispielimplementierung des oben beschriebenen Workflows zum Abrufen der Generierung einer WorkRequest
.
// Get instance of WorkManager.
val workManager = WorkManager.getInstance(context)
// Retrieve WorkInfo instance.
val workInfo = workManager.getWorkInfoById(oldWorkRequestId)
// Call getGeneration to retrieve the generation.
val generation = workInfo.getGeneration()
Richtlinien für die Aktualisierung von Arbeitsergebnissen
Zuvor wurde für die Aktualisierung regelmäßiger Arbeiten empfohlen, ein PeriodicWorkRequest
mit der Richtlinie ExistingPeriodicWorkPolicy.REPLACE
in die Warteschlange zu stellen.
Wenn es eine ausstehende PeriodicWorkRequest
mit derselben eindeutigen id
gibt, wird die neue Arbeitsanfrage abgebrochen und gelöscht. Diese Richtlinie wurde zugunsten des Workflows mit ExistingPeriodicWorkPolicy.UPDATE
verworfen.
Wenn du beispielsweise enqueueUniquePeriodicWork
mit einer PeriodicWorkRequest
verwendest, kannst du das neue PeriodicWorkRequest
mit der Richtlinie ExistingPeriodicWorkPolicy.UPDATE
initialisieren. Gibt es eine ausstehende PeriodicWorkRequest
mit demselben eindeutigen Namen, wird sie von WorkManager auf die neue Spezifikation aktualisiert. Für diesen Workflow ist die Verwendung von updateWork()
nicht erforderlich.