Aufgaben aktualisieren, die sich bereits in die Warteschlange eingereiht haben

Mit WorkManager können Sie ein WorkRequest aktualisieren, nachdem Sie in die Warteschlange gestellt wurde. Dies ist oft bei größeren Apps erforderlich, die sich häufig ändern. oder ihre Worker spontan aktualisieren müssen. Ab WorkManager Version 2.8.0 ist die updateWork() API dafür die richtige Lösung.

Mit der Methode updateWork() können Sie bestimmte Aspekte eines können Sie sofort WorkRequest starten, ohne sie manuell und eine neue in die Warteschlange stellen. Dies vereinfacht die Entwicklung erheblich. .

Stornierung der Arbeit vermeiden

Vermeiden Sie es, vorhandene WorkRequests abzubrechen und eine neue eins. Das kann dazu führen, dass die App bestimmte Aufgaben wiederholt und dass Sie dann möglicherweise um eine beträchtliche Menge an zusätzlichem Code zu schreiben.

Die folgenden Beispiele zeigen, wo das Abbrechen einer WorkRequest zu Schwierigkeiten:

  • Backend-Anfrage:Wenn Sie eine Worker während der Verarbeitung abbrechen eine Nutzlast zum Senden an den Server hat, muss die neue Worker von vorn beginnen und die potenziell teure Nutzlast neu zu berechnen.
  • Planung:Wenn Sie eine PeriodicWorkRequest stornieren und wie die neue PeriodicWorkRequest nach demselben Zeitplan ausgeführt werden soll, einen Zeitversatz zu berechnen, damit die neue Ausführungszeit mit der vorherigen Arbeitsanfrage.

Mit der updateWork() API können Sie die Einschränkungen und ohne den Vorgang abzubrechen und eine neue Anfrage in die Warteschlange zu stellen.

Wann die Arbeit abgebrochen werden sollte

In manchen Fällen empfiehlt es sich, eine WorkRequest direkt zu stornieren, anstatt Rufen Sie updateWork() an. So ändern Sie den Parameter der Arbeit, die Sie in die Warteschlange eingereiht haben.

Wann muss die Arbeitsadresse aktualisiert werden?

Stellen Sie sich eine Foto-App vor, mit der die Fotos des Nutzers täglich gesichert werden. Sie enthält PeriodicWorkRequest dazu in die Warteschlange gestellt. Für WorkRequest gelten Einschränkungen bei denen das Gerät geladen und mit dem WLAN verbunden sein muss.

Allerdings lädt der Nutzer sein Gerät nur 20 Minuten am Tag mit einem Ladegerät. In diesem Fall kann es sinnvoll sein, die WorkRequest zu aktualisieren, um die damit die Fotos auch dann hochgeladen werden können, nicht vollständig geladen ist.

In diesem Fall können Sie die Methode updateWork() verwenden, um die Arbeit die Einschränkungen der Anfrage.

Anleitung zum Aktualisieren der Arbeitsadresse

Die Methode updateWork() bietet eine einfache Möglichkeit zum Aktualisieren eines vorhandenen WorkRequest, ohne den Vorgang abzubrechen und einen neuen in die Warteschlange stellen zu müssen.

So verwenden Sie die Aktualisierung von Aufgaben in der Warteschlange:

  1. 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 oder durch manuelles Speichern der ID aus der ursprünglichen WorkRequest zum späteren Abrufen mit der öffentlichen Property WorkRequest.id, bevor Sie es in die Warteschlange stellen.
  2. Create new WorkRequest (Neue WorkRequest erstellen): Erstellen Sie eine neue WorkRequest und verwenden Sie WorkRequest.Builder.setID(), um seine ID so festzulegen, dass sie mit der des vorhandenen übereinstimmt WorkRequest
  3. Einschränkungen festlegen: Verwenden Sie WorkRequest.Builder.setConstraints(), um die WorkManager-Einschränkungen.
  4. updateWork aufrufen: Übergeben Sie den neuen WorkRequest an updateWork().

Arbeitsbeispiel aktualisieren

Hier ist ein Beispiel-Code-Snippet in Kotlin, das zeigt, wie die updateWork()-Methode zum Ändern der Akkueinschränkungen eines verwendeten WorkRequest-Geräts um Fotos hochzuladen:

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 ListenableFuture<UpdateResult> zurück. Das angegebene UpdateResult kann einen von mehreren Werten haben, die angeben, ob Der WorkManager konnte Ihre Änderungen übernehmen. Außerdem wird angegeben, wann um die Änderung zu übernehmen.

Weitere Informationen findest du in den updateWork() und UpdateResult. Referenz.

Aufgaben mit mehreren Generationen im Blick behalten

Jedes Mal, wenn Sie eine WorkRequest aktualisieren, wird die Generierung um eins erhöht. Dieses kannst du genau verfolgen, welches WorkRequest sich gerade in der Warteschlange befindet. Generierungen bieten mehr Kontrolle beim Beobachten, Nachverfolgen und Testen von Arbeiten -Anfragen.

So rufen Sie eine WorkRequest ab:

  1. WorkInfo: Rufen Sie WorkManager.getWorkInfoById() auf, um eine Instanz abzurufen. von WorkInfo für WorkRequest.
    • Sie können eine von mehreren Methoden aufrufen, die ein WorkInfo zurückgeben. Weitere Informationen finden Sie in der WorkManager-Referenz.
  2. getGeneration: Aufruf von getGeneration() auf Instanz von WorkInfo Die zurückgegebene Int entspricht der Generierung des WorkRequest.
    • Es gibt weder ein Generationsfeld noch eine Eigenschaft, sondern nur das Feld WorkInfo.getGeneration()-Methode.

Beispiel für die Titelgenerierung

Im Folgenden finden Sie eine Beispielimplementierung des oben beschriebenen Workflows für Generierung eines WorkRequests wird abgerufen.

// 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 Aufgaben

Bisher war die empfohlene Lösung zum Aktualisieren regelmäßiger Arbeiten das Einreihen einer PeriodicWorkRequest durch die Richtlinie ExistingPeriodicWorkPolicy.REPLACE. Wenn es eine ausstehende PeriodicWorkRequest mit derselben eindeutigen id gab, wird die neue wird sie abgebrochen und gelöscht. Diese Richtlinie wurde eingestellt in mit der ExistingPeriodicWorkPolicy.UPDATE zugunsten des Workflows aus.

Wenn Sie beispielsweise enqueueUniquePeriodicWork mit einem PeriodicWorkRequest können Sie die neue PeriodicWorkRequest mit der ExistingPeriodicWorkPolicy.UPDATE-Richtlinie. Wenn ein ausstehender PeriodicWorkRequest mit demselben eindeutigen Namen hat, aktualisiert WorkManager sie auf die neuen Spezifikation. Nach diesem Workflow ist es nicht erforderlich, updateWork()