In diesem Artikel werden wir über ein Problem mit JobIntentService sprechen, zu dem es viele Fragen zu den entsprechenden Ressourcen und Berichten im Google Bug Tracker gibt. Und auch über den Grund, warum Google es nach allem nicht als Fehler ansieht und diese Berichte schließt.
Einführung
JobIntentServices wurden für Hintergrundarbeiten erstellt. Sie wurden häufig in Android 8 und höher verwendet, als die Möglichkeit, Dienste im Hintergrund zu verwenden, verschwand.
Tatsächlich ersetzen sie Dienste im Hintergrund und werden auch vom Taskplaner (JobScheduler) gesteuert.
Somit hat das System die Möglichkeit, den Fortschritt von Aufgaben im Hintergrund zu steuern und auch die Wakelocks selbst zu steuern, wodurch es möglich wurde, den Batterieverbrauch des Geräts zu optimieren und die falsche Verwendung von Wakelocks durch Entwickler zu vermeiden. Durch diese Schritte konnten Situationen minimiert werden, in denen das Gerät nicht in den Ruhemodus (Doze-Modus) wechseln kann, was sich wiederum auf die Batteriesparleistung auswirkt.
Kurz über JobIntentService
Im Wesentlichen ist der JobIntentService derselbe IntentService, der vom Taskplaner (JobScheduler) gesteuert wird.
Wird im Hintergrund-Thread von AsyncTask ausgeführt.
In Versionen von Android 4.4 und niedriger wird der übliche IntentService verwendet.
Eine ausführliche Beschreibung finden Sie in der Dokumentation.
Lebenszyklus und Fallstricke
Beide Arten von Aufgaben haben den gleichen Lebenszyklus. Aufgaben werden vom Handler gesteuert und haben Status.
Obwohl auf diese Zustände extern nicht zugegriffen werden kann, löst das System unter bestimmten Umständen Ausnahmen aus, bei denen die Anwendung abstürzt. Diese Verhaltensweisen sind für viele Entwickler ein Problem und Kopfschmerzen und haben leider keine einfache Lösung. Zunächst untersuchen wir den Status und den Lebenszyklus von Aufgaben und prüfen dann mögliche Lösungen.
Taskstatussequenz

BINDING - Timeout für den Status der Aufgabenerstellung (Servicebindung) 18 Sekunden.
STARTING - Startstatus der Task, Zeitüberschreitung 8 Sekunden.
AUSFÜHREN - Status der Aufgabenausführung, Zeitüberschreitung 10 Minuten.
STOPPING - Task-Stopp-Status (z. B. nach dem Aufruf von cancel ()), Zeitüberschreitung 8 Sekunden.
FINISHED - der Endzustand der abgeschlossenen Aufgabe, der letzte Zustand im Lebenszyklus der Aufgabe.
Vereinfachtes Task-Lebenszyklusdiagramm

Jeder Taskstatus hat ein eigenes Timeout. Nach einer Zeitüberschreitung wird die Aufgabe unabhängig von ihrem Status unterbrochen. Tatsächlich ist dies ein Timeout-Mechanismus und seitdem eine Falle Nach dem Timeout löst das System eine Ausnahme vom Typ java.lang.SecurityException
und die Anwendung stürzt mit der folgenden Meldung ab. Der Caller no longer running, last stopped +1s600ms because: timed out while starting
wobei +1s600ms
die Zeit ist, die seit dem Timeout vergangen ist In dem Moment, in dem die Ausnahme ausgelöst wurde, gibt der „Grund“ ( because: timed out while starting
Zeitüberschreitung because: timed out while starting
) an, in welchem Status sich die Aufgabe befand, als das Zeitlimit abgelaufen ist.
Schlussfolgerungen
Wie die Erfahrung zeigt, sind diese Ausnahmen in ziemlich geladenen Anwendungen zu finden.
Zur Unterstützung dieses Problems kann man sowohl auf schwachen als auch auf Top-Geräten beobachten. Dieses Problem wird auch durch ausgelöste Ausnahmen mit Timeout-Meldungen angezeigt. Dementsprechend bietet sich die Entscheidung zum Entladen der Anwendung und zur Optimierung der Verwendung von JobIntentServices an, um beispielsweise Situationen zu vermeiden, in denen mehrere JobIntentServices parallel gestartet werden. Die zweite Lösung, die in einigen Fällen trivialer und manchmal komplizierter als die erste Option ist, ist die Verwendung von JobService.
Wenn Sie dieses Problem googeln, können Sie auch auf andere "zweifelhafte" Optionen zur Lösung dieses Problems stoßen. Beispielsweise sehen Sie die folgenden Links:
Variante 1
Option 2
Option 3
PS
Derzeit bereitet Google einen guten Ersatz für JobService und JobIntentService vor - dies sind Worker und WorkManger aus dem androidx.work-Paket.
Leider sind diese Tools noch nicht produktionsbereit und weisen eine Reihe von Fehlern auf. Wie Tests gezeigt haben, lösen sie bereits jetzt das oben beschriebene Problem.