Unter der Haube eines JobIntentService

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


Bild
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


Bild
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.

Source: https://habr.com/ru/post/de432576/


All Articles