Arbeitsanfragen definieren

Im Startleitfaden wurde erklärt, wie du ein einfaches WorkRequest erstellst. und es in die Warteschlange stellen.

In diesem Leitfaden erfahren Sie, wie Sie WorkRequest-Objekte definieren und anpassen um häufige Anwendungsfälle zu bewältigen, z. B.:

  • Einmalige und wiederkehrende Aufgaben planen
  • Arbeitsbeschränkungen festlegen, z. B. WLAN oder Aufladen
  • Eine minimale Verzögerung bei der Ausführung der Arbeit garantieren
  • Wiederholungs- und Backoff-Strategien festlegen
  • Eingabedaten übergeben
  • Zusammengehörige Arbeiten mithilfe von Tags gruppieren

Übersicht

Die Arbeit wird im WorkManager über ein WorkRequest definiert. Um Aufgaben mit WorkManager planen können. Sie müssen zuerst einen WorkRequest-Objekt und fügen es dann in die Warteschlange ein.

Kotlin

val myWorkRequest = ...
WorkManager.getInstance(myContext).enqueue(myWorkRequest)

Java

WorkRequest myWorkRequest = ...
WorkManager.getInstance(myContext).enqueue(myWorkRequest);

Das WorkRequest-Objekt enthält alle Informationen, die WorkManager für Ihre Arbeit zu planen und durchzuführen. Sie enthält Einschränkungen, die für Ihre wie Verzögerungen oder Wiederholungsintervalle, Wiederholungsversuche Konfiguration und können Eingabedaten enthalten, wenn Ihre Arbeit davon abhängt.

WorkRequest selbst ist eine abstrakte Basisklasse. Es gibt zwei abgeleiteten Implementierungen dieser Klasse, mit denen Sie die Anfrage erstellen können, OneTimeWorkRequest und PeriodicWorkRequest. Wie der Name schon sagt, ist OneTimeWorkRequest nützlich für die Planung nicht wiederholenden Arbeiten, während PeriodicWorkRequest eher für das Planen von Arbeiten, die sich in Intervallen wiederholen.

Einmalige Arbeiten planen

Für eine einfache Arbeit, die keine zusätzliche Konfiguration erfordert, verwenden Sie die statische Methode from:

Kotlin

val myWorkRequest = OneTimeWorkRequest.from(MyWork::class.java)

Java

WorkRequest myWorkRequest = OneTimeWorkRequest.from(MyWork.class);

Für komplexere Aufgaben können Sie einen Builder verwenden:

Kotlin

val uploadWorkRequest: WorkRequest =
   OneTimeWorkRequestBuilder<MyWork>()
       // Additional configuration
       .build()

Java

WorkRequest uploadWorkRequest =
   new OneTimeWorkRequest.Builder(MyWork.class)
       // Additional configuration
       .build();

Schnelle Arbeiten planen

Mit WorkManager 2.7.0 wurde das Konzept der beschleunigten Arbeit eingeführt. Dadurch können Sie WorkManager, um wichtige Arbeiten auszuführen und dem System eine bessere Kontrolle zu geben. mehr Zugriff auf Ressourcen hat.

Schnelle Arbeiten zeichnen sich durch folgende Merkmale aus:

  • Wichtigkeit: Beschleunigte Arbeiten sind besser für Aufgaben, die für den Nutzer oder vom Nutzer initiiert werden.
  • Geschwindigkeit: Schnelle Bearbeitung eignet sich am besten für kurze Aufgaben, die sofort beginnen und innerhalb weniger Minuten abgeschlossen werden.
  • Kontingente: Ein Kontingent auf Systemebene, das die Ausführungszeit im Vordergrund begrenzt bestimmt, ob ein beschleunigter Job gestartet werden kann.
  • Energiesparmodus: Einschränkungen der Energieverwaltung, z. B. Akku Die Funktion „Sparmodus“ und „Stromsparmodus“ wirken sich weniger wahrscheinlich auf die Beschleunigung von Arbeitsabläufen aus.
  • Latenz: Das System führt sofort beschleunigte Aufgaben aus, vorausgesetzt, der der aktuellen Arbeitslast des Systems ermöglicht. Das bedeutet, dass es sich um Latenzen handelt, sensible Daten und können nicht für eine spätere Ausführung geplant werden.

Ein möglicher Anwendungsfall für beschleunigte Arbeiten ist eine Chat-App, wenn Nutzende möchte eine Nachricht oder ein angehängtes Bild senden. Eine App, die eine wenn Sie z. B. die Möglichkeit haben, die Expressbearbeitung zu verwenden. Dies ist da diese Aufgaben für Nutzende wichtig sind, schnell im Hintergrund ausführen, müssen sofort beginnen und sollten auch Der Nutzer schließt die App.

Kontingente

Das System muss einem beschleunigten Job die Ausführungszeit zuweisen, bevor er ausgeführt werden kann. Die Ausführungszeit ist nicht unbegrenzt. Vielmehr erhält jede Anwendung ein Kontingent, der Ausführungszeit. Wann Ihre Anwendung ihre Ausführungszeit verwendet und ihre zugewiesenes Kontingent können Sie aktualisiert wird. Dadurch kann Android Ressourcen effektiver zwischen Anwendungen.

Die Ausführungszeit, die einer Anwendung zur Verfügung steht, hängt vom Standby-Bucket und die Prozesswichtigkeit.

Sie können festlegen, was passiert, wenn das Ausführungskontingent ein um den Job sofort auszuführen. Weitere Informationen finden Sie in den nachfolgenden Snippets.

Beschleunigte Bearbeitung von Aufgaben

Ab WorkManager 2.7 kann deine App setExpedited() aufrufen, um zu erklären, Ein WorkRequest sollte mit einem Express-Job so schnell wie möglich ausgeführt werden. Die Das folgende Code-Snippet zeigt ein Beispiel für die Verwendung von setExpedited():

Kotlin

val request = OneTimeWorkRequestBuilder<SyncWorker>()
    .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
    .build()

WorkManager.getInstance(context)
    .enqueue(request)

Java

OneTimeWorkRequest request = new OneTimeWorkRequestBuilder<T>()
    .setInputData(inputData)
    .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
    .build();

In diesem Beispiel initialisieren wir eine Instanz von OneTimeWorkRequest und rufen setExpedited(). Diese Anfrage wird dann beschleunigt. Wenn das Kontingent ermöglicht, wird sie sofort im Hintergrund ausgeführt. Wenn das Kontingent festgelegt wurde, gibt der Parameter OutOfQuotaPolicy an, dass die Anfrage als normale und nicht beschleunigte Arbeit durchgeführt werden.

Abwärtskompatibilität und Dienste im Vordergrund

Um die Abwärtskompatibilität für beschleunigte Jobs aufrechtzuerhalten, kann WorkManager einen Dienst im Vordergrund auf Plattformversionen ausführen, die älter als Android 12 sind. Dienste im Vordergrund können dem Nutzer eine Benachrichtigung anzeigen.

Die Methoden getForegroundInfoAsync() und getForegroundInfo() im Worker Zulassen, dass WorkManager beim Aufruf von setExpedited() eine Benachrichtigung anzeigt vor Android 12.

Ein ListenableWorker muss die getForegroundInfo-Methode implementieren, wenn Sie möchte anfordern, dass die Task als beschleunigten Job ausgeführt wird.

Bei einer Ausrichtung auf Android 12 oder höher bleiben Dienste im Vordergrund für Sie mit der entsprechenden setForeground-Methode.

Mitarbeiter

Beschäftigte wissen nicht, ob ihre Arbeit beschleunigt wird oder nicht. Aber können Mitarbeiter unter einigen Android-Versionen eine Benachrichtigung anzeigen, WorkRequest wurde beschleunigt.

Dazu stellt WorkManager die Methode getForegroundInfoAsync() bereit. die Sie implementieren müssen, damit WorkManager eine Benachrichtigung zum Starten eines ForegroundService.

Mitarbeiter

Wenn Sie CoroutineWorker verwenden, müssen Sie getForegroundInfo() implementieren. Anschließend sie innerhalb von doWork() an setForeground() übergeben. Dadurch wird die in Android-Versionen vor 12 erhalten.

Betrachten Sie das folgende Beispiel:

  class ExpeditedWorker(appContext: Context, workerParams: WorkerParameters):
   CoroutineWorker(appContext, workerParams) {

   override suspend fun getForegroundInfo(): ForegroundInfo {
       return ForegroundInfo(
           NOTIFICATION_ID, createNotification()
       )
   }

   override suspend fun doWork(): Result {
       TODO()
   }

    private fun createNotification() : Notification {
       TODO()
    }

}

Kontingentrichtlinien

Sie können festlegen, was mit Express-Arbeit geschehen soll, wenn Ihre App ihre Ausführungskontingent. Um fortzufahren, müssen Sie setExpedited() übergeben:

  • OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST, wodurch der Job als normale Arbeitsanfrage ausgeführt werden. Dies wird im Snippet oben verdeutlicht.
  • OutOfQuotaPolicy.DROP_WORK_REQUEST, wodurch die Anfrage abgebrochen wird, wenn dass das Kontingent nicht ausreicht.

Beispiel-App

Ein vollständiges Beispiel dafür, wie WorkManager 2.7.0 beschleunigte Arbeit nutzt, im WorkManagerSample auf GitHub.

Aufgeschobene Schnellarbeiten

Das System versucht, einen bestimmten Express-Job so schnell wie möglich nach der aufgerufen wird. Wie bei anderen Arten von Jobs kann das System kann den Start neuer beschleunigter Arbeiten verzögern, wie in den folgenden Fällen:

  • Last: Die Systemlast ist zu hoch. Dies kann auftreten, wenn zu viele Jobs bereits ausgeführt wird oder das System nicht über genügend Arbeitsspeicher verfügt.
  • Kontingent: Das Limit für das beschleunigte Jobkontingent wurde überschritten. Schnelle Arbeit verwendet ein Kontingentsystem, das auf App-Standby-Buckets basiert und maximale Ausführungszeit innerhalb eines rollierenden Zeitfensters. Die verwendeten Kontingente für sind für beschleunigte Arbeiten strenger als für andere Arten von Hintergrundjobs ein.

Regelmäßige Arbeiten planen

Ihre App kann gelegentlich erfordern, dass bestimmte Arbeiten regelmäßig ausgeführt werden. Beispiel: sollten Sie Ihre Daten regelmäßig sichern, neue Inhalte oder auf einen Server hochladen.

So verwenden Sie PeriodicWorkRequest zum Erstellen eines WorkRequest-Objekt, das regelmäßig ausgeführt wird:

Kotlin

val saveRequest =
       PeriodicWorkRequestBuilderS<aveImageToFileWorker(>1, TimeUnit.HOURS)
    // Additional configuration
           .build()

Java

PeriodicWorkRequest saveRequest =
       new PeriodicWorkRequest.Builder(SaveImageToFileWorker.class, 1, TimeUnit.HOURS)
           // Constraints
           .build();

In diesem Beispiel werden die Arbeiten mit einem Intervall von einer Stunde geplant.

Der Intervallzeitraum ist definiert als die minimale Zeit zwischen den Wiederholungen. Die Wann genau der Worker ausgeführt wird, hängt von den Einschränkungen ab, die Sie in Ihrem WorkRequest-Objekt verwenden, und bei den durch das System.

Flexible Ausführungsintervalle

Falls der Zeitpunkt der Ausführung aufgrund Ihrer Arbeit schwierig ist, können Sie Ihre PeriodicWorkRequest so, dass sie nur flexibel ist und Intervall innerhalb jedes Intervallzeitraums, wie in Abbildung 1 dargestellt.

Sie können für einen regelmäßigen Job ein flexibles Intervall festlegen. Sie definieren ein Wiederholungsintervall,
und ein flexibles Intervall, das eine bestimmte Zeit am Ende des
Wiederholungsintervall. WorkManager versucht, den Job während der
Flex-Intervall in jedem Zyklus.

Abbildung 1: Das Diagramm zeigt Wiederholungsintervalle mit flexiblem Zeitraum. die die Arbeit ausführen kann.

Um regelmäßige Arbeit mit einem flexiblen Zeitraum zu definieren, übergeben Sie eine flexInterval zusammen mit das repeatInterval beim Erstellen des PeriodicWorkRequest. Der flexible Zeitraum beginnt um repeatInterval - flexInterval und endet am Ende des Intervalls.

Hier sehen Sie ein Beispiel für regelmäßige Arbeiten, die in den letzten 15 ausgeführt werden können. Minuten jeder einstündigen Periode.

Kotlin

val myUploadWork = PeriodicWorkRequestBuilderS<aveImageToFileWorker(>
       1, TimeUnit.HOURS, // repeatInterval (the period cycle)
       15, TimeUnit.MINUTES) // flexInterval
    .build()

Java

WorkRequest saveRequest =
       new PeriodicWorkRequest.Builder(SaveImageToFileWorker.class,
               1, TimeUnit.HOURS,
               15, TimeUnit.MINUTES)
           .build();

Das Wiederholungsintervall muss größer oder gleich sein. PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS und der Flex Intervall muss größer oder gleich sein PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS.

Auswirkungen von Beschränkungen auf regelmäßige Arbeit

Sie können Einschränkungen auf periodische Arbeiten anwenden. Sie könnten zum Beispiel ein Arbeitsanfrage, sodass die Arbeit nur dann ausgeführt wird, wenn der Nutzer Gerät wird geladen. Selbst wenn das festgelegte Wiederholungsintervall durchläuft, PeriodicWorkRequest wird erst ausgeführt, wenn diese Bedingung erfüllt ist. Dies könnte eine bestimmte Ausführung Ihrer Arbeit verzögert oder sogar übersprungen wird, Bedingungen innerhalb des Ausführungsintervalls nicht erfüllt sind.

Arbeitsbeschränkungen

Einschränkungen stellen sicher, dass die Arbeit verzögert wird, bis optimale Bedingungen erfüllt sind. Die folgenden Einschränkungen sind für WorkManager verfügbar.

Netzwerktyp Beschränkt den Netzwerktyp, der für die Ausführung Ihrer Arbeit erforderlich ist. Beispiel: WLAN (UNMETERED).
Akkulaufzeit nicht niedrig Ist sie auf „true“ gesetzt, wird die Arbeit nicht ausgeführt, wenn der Akku des Geräts schwach ist.
Erfordert Aufladen Ist sie auf „true“ gesetzt, wird die Arbeit nur dann ausgeführt, wenn das Gerät geladen wird.
DeviceIdle Ist sie auf „true“ gesetzt, muss das Gerät des Nutzers inaktiv sein, damit die Arbeit ausgeführt werden kann. Dies kann nützlich sein, wenn Sie Batch-Vorgänge ausführen, die sich andernfalls negativ auf die Leistung anderer Apps auswirken könnten, die auf dem Gerät des Nutzers ausgeführt werden.
Speicher nicht niedrig Wenn die Richtlinie auf „true“ gesetzt ist, wird Ihre Arbeit nicht ausgeführt, wenn der Speicherplatz des Nutzers auf dem Gerät zu gering ist.

Um eine Reihe von Einschränkungen zu erstellen und mit Arbeit zu verknüpfen, erstellen Sie eine Constraints-Instanz mithilfe der Contraints.Builder() und weisen Sie sie der WorkRequest.Builder()

Mit dem folgenden Code wird beispielsweise eine Arbeitsanfrage erstellt, die nur ausgeführt wird, wenn der das Gerät des Nutzers geladen wird und mit einem WLAN verbunden ist:

Kotlin

val constraints = Constraints.Builder()
   .setRequiredNetworkType(NetworkType.UNMETERED)
   .setRequiresCharging(true)
   .build()

val myWorkRequest: WorkRequest =
   OneTimeWorkRequestBuilderM<yWork(>)
       .setConstraints(constraints)
       .build()

Java

Constraints constraints = new Constraints.Builder()
       .setRequiredNetworkType(NetworkType.UNMETERED)
       .setRequiresCharging(true)
       .build();

WorkRequest myWorkRequest =
       new OneTimeWorkRequest.Builder(MyWork.class)
               .setConstraints(constraints)
               .build();

Sind mehrere Einschränkungen angegeben, wird Ihre Arbeit nur ausgeführt, wenn alle Beschränkungen eingehalten werden.

Falls eine Einschränkung nicht erfüllt wird, während Ihre Arbeit ausgeführt wird, WorkManager beendet den Worker. Die Arbeit wird wiederholt, sobald alle Beschränkungen eingehalten werden.

Verzögerte Arbeit

Für den Fall, dass Ihre Arbeit keine Einschränkungen aufweist oder alle Einschränkungen erfüllt, wenn Ihre Arbeit in die Warteschlange eingereiht wird, kann das System die Arbeit sofort. Wenn Sie nicht möchten, dass die Arbeit sofort ausgeführt wird, können Sie mit einer minimalen Verzögerung beginnen.

Hier ist ein Beispiel dafür, wie Sie Ihre Arbeit so einstellen können, dass sie mindestens 10 Minuten nach der Ausführung ausgeführt wird wurde zur Warteschlange hinzugefügt.

Kotlin

val myWorkRequest = OneTimeWorkRequestBuilderM<yWork(>)
   .setInitialDelay(10, TimeUnit.MINUTES)
   .build()

Java

WorkRequest myWorkRequest =
      new OneTimeWorkRequest.Builder(MyWork.class)
               .setInitialDelay(10, TimeUnit.MINUTES)
               .build();

Das Beispiel zeigt, wie eine anfängliche Verzögerung für eine OneTimeWorkRequest können Sie auch eine anfängliche Verzögerung PeriodicWorkRequest. In diesem Fall wird nur der erste Durchlauf Ihrer verzögert sich.

Wiederholungs- und Backoff-Richtlinie

Wenn WorkManager Ihre Arbeit wiederholen soll, können Sie Result.retry() von Ihrem Worker. Ihre Arbeit ist dann den Termin gemäß einer Backoff-Verzögerung und einer Backoff-Richtlinie verschoben.

  • Die Backoff-Verzögerung gibt die Mindestwartezeit an, bevor ein neuer Versuch unternommen wird. Ihre Arbeit nach dem ersten Versuch. Dieser Wert muss mindestens 10 Sekunden betragen (oder MIN_BACKOFF_MILLIS).

  • In der Backoff-Richtlinie wird definiert, wie die Backoff-Verzögerung nachfolgende Wiederholungsversuche. WorkManager unterstützt zwei Backoff-Richtlinien: LINEAR und EXPONENTIAL.

Jede Arbeitsanfrage hat eine Backoff-Richtlinie und eine Backoff-Verzögerung. Die Standardrichtlinie ist EXPONENTIAL mit einer Verzögerung von 30 Sekunden. Sie können dies jedoch in Ihren Konfiguration von Arbeitsanfragen.

Hier ist ein Beispiel für die Anpassung der Backoff-Verzögerung und der Richtlinie.

Kotlin

val myWorkRequest = OneTimeWorkRequestBuilderM<yWork(>)
   .setBackoffCriteria(
       BackoffPolicy.LINEAR,
       OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
       TimeUnit.MILLISECONDS)
   .build()

Java

WorkRequest myWorkRequest =
       new OneTimeWorkRequest.Builder(MyWork.class)
               .setBackoffCriteria(
                       BackoffPolicy.LINEAR,
                       OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
                       TimeUnit.MILLISECONDS)
               .build();

In diesem Beispiel ist die minimale Backoff-Verzögerung auf den minimal zulässigen Wert gesetzt, 10 Sekunden. Da die Richtlinie LINEAR ist, erhöht sich das Wiederholungsintervall um etwa 10 Sekunden lang. Zum Beispiel: Die erste Ausführung nach Result.retry() wird nach 10 Sekunden noch einmal versucht, gefolgt von 20, 30, 40 usw., falls das Werk weiter Result.retry() nach weiteren Versuchen. Wenn die Backoff-Richtlinie auf EXPONENTIAL liegt die Wiederholungsdauer näher an 20, 40, 80 usw. aktiviert.

Tag-Arbeit

Jede Arbeitsanfrage hat eine eindeutige Kennung, anhand derer die später ausgeführt werden, um sie abzubrechen oder den Fortschritt zu beobachten.

Wenn Sie eine Gruppe logisch zusammenhängender Arbeiten haben, kann es auch hilfreich sein, diese Arbeitselemente zu taggen. Mithilfe von Tagging können Sie mit einer Gruppe von Mitarbeitern arbeiten. miteinander verknüpfen.

Beispiel: WorkManager.cancelAllWorkByTag(String) bricht alle Arbeitsanfragen mit einem bestimmten Tag WorkManager.getWorkInfosByTag(String) gibt eine Liste der WorkInfo-Objekte, mit denen der aktuelle Arbeitsstatus ermittelt werden kann.

Der folgende Code zeigt, wie Sie eine Bereinigung hinzufügen zu Ihrer Arbeit hinzufügen:

Kotlin

val myWorkRequest = OneTimeWorkRequestBuilderM<yWork(>)
   .addTag("cleanup")
   .build()

Java

WorkRequest myWorkRequest =
       new OneTimeWorkRequest.Builder(MyWork.class)
       .addTag("cleanup")
       .build();

Schließlich können einer einzelnen Arbeitsanfrage mehrere Tags hinzugefügt werden. Intern Tags werden als eine Reihe von Zeichenfolgen gespeichert. Um die Gruppe von Tags abzurufen, die mit der WorkRequest können Sie WorkInfo.getTags() verwenden.

Sie können die Tags Ihrer Worker-Klasse über ListenableWorker.getTags() verwenden.

Eingabedaten zuweisen

Möglicherweise sind für Ihre Arbeit Eingabedaten erforderlich. Arbeiten Sie beispielsweise für das Hochladen eines Bildes benötigt wird, kann es sein, dass der URI des Bildes als Eingabe.

Eingabewerte werden als Schlüssel/Wert-Paare in einem Data-Objekt gespeichert und können in der Arbeitsanfrage festgelegt werden. WorkManager übermittelt die Eingabe Data an wenn es die Arbeit ausführt. Die Klasse Worker hat Zugriff Eingabeargumente durch Aufrufen von Worker.getInputData(). Die Code unten zeigt, wie Sie eine Worker-Instanz erstellen, die Eingabedaten und wie diese in Ihrer Arbeitsanfrage gesendet werden.

Kotlin

// Define the Worker requiring input
class UploadWork(appContext: Context, workerParams: WorkerParameters)
   : Worker(appContext, workerParams) {

   override fun doWork(): Result {
       val imageUriInput =
           inputData.getString("IMAGE_URI") ?: return Result.failure()

       uploadFile(imageUriInput)
       return Result.success()
   }
   ...
}

// Create a WorkRequest for your Worker and sending it input
val myUploadWork = OneTimeWorkRequestBuilderU<ploadWork(>)
   .setInputData(workDataOf(
       "IMAGE_URI" to "http://..."
   ))
   .build()

Java

// Define the Worker requiring input
public class UploadWork extends Worker {

   public UploadWork(Context appContext, WorkerParameters workerParams) {
       super(appContext, workerParams);
   }

   @NonNull
   @Override
   public Result doWork() {
       String imageUriInput = getInputData().getString("IMAGE_URI");
       if(imageUriInput == null) {
           return Result.failure();
       }

       uploadFile(imageUriInput);
       return Result.success();
   }
   ...
}

// Create a WorkRequest for your Worker and sending it input
WorkRequest myUploadWork =
      new OneTimeWorkRequest.Builder(UploadWork.class)
           .setInputData(
               new Data.Builder()
                   .putString("IMAGE_URI", "http://...")
                   .build()
           )
           .build();

Auf ähnliche Weise kann die Klasse Data verwendet werden, um einen Rückgabewert auszugeben. Eingabe und Ausgabedaten werden im Abschnitt Eingabeparameter und zurückgegebene Werte.

Nächste Schritte

Auf der Seite Zustände und Beobachtung finden Sie weitere Informationen zum Arbeitsstatus. und wie Sie den Fortschritt Ihrer Arbeit überwachen.