Einschränkungen bei der Hintergrundausführung

Wenn eine App im Hintergrund ausgeführt wird, verbraucht sie einige der begrenzten Ressourcen des Geräts, z. B. den Arbeitsspeicher. Dies kann die Nutzerfreundlichkeit beeinträchtigen, insbesondere wenn der Nutzer eine ressourcenintensive App verwendet, z. B. ein Spiel spielt oder sich ein Video ansieht. Um die Nutzerfreundlichkeit zu verbessern, schränkt Android 8.0 (API-Ebene 26) die Möglichkeiten von Apps ein, die im Hintergrund ausgeführt werden. In diesem Dokument werden die Änderungen am Betriebssystem beschrieben und wie Sie Ihre App so aktualisieren können, dass sie auch unter den neuen Einschränkungen ordnungsgemäß funktioniert.

Übersicht

Viele Android-Apps und ‑Dienste können gleichzeitig ausgeführt werden. Ein Nutzer könnte beispielsweise in einem Fenster ein Spiel spielen, in einem anderen Fenster im Internet surfen und mit einer dritten App Musik abspielen. Je mehr Apps gleichzeitig ausgeführt werden, desto stärker wird das System belastet. Wenn zusätzliche Apps oder Dienste im Hintergrund ausgeführt werden, wird das System zusätzlich belastet. Dies kann zu einer schlechten Nutzererfahrung führen, z. B. wenn die Musik-App plötzlich geschlossen wird.

Um die Wahrscheinlichkeit dieser Probleme zu verringern, schränkt Android 8.0 die Möglichkeiten von Apps ein, wenn Nutzer nicht direkt mit ihnen interagieren. Apps sind auf zwei Arten eingeschränkt:

  • Einschränkungen für Hintergrunddienste: Wenn eine App inaktiv ist, ist die Nutzung von Hintergrunddiensten eingeschränkt. Dies gilt nicht für Dienste im Vordergrund, die für Nutzer besser sichtbar sind.

  • Einschränkungen bei Übertragungen: Mit wenigen Ausnahmen können Apps sich nicht über ihr Manifest für implizite Übertragungen registrieren. Sie können sich aber weiterhin zur Laufzeit für diese Übertragungen registrieren und mithilfe des Manifests für explizite Übertragungen und Übertragungen registrieren, die speziell auf ihre App ausgerichtet sind.

In den meisten Fällen können Apps diese Einschränkungen durch die Verwendung von JobScheduler-Jobs umgehen. Mit diesem Ansatz kann eine App Aufgaben ausführen, wenn sie nicht aktiv ausgeführt wird. Das System hat jedoch weiterhin die Möglichkeit, diese Jobs so zu planen, dass sie die Nutzerfreundlichkeit nicht beeinträchtigen. Android 8.0 bietet mehrere Verbesserungen an JobScheduler, die es einfacher machen, Dienste und Broadcastempfänger durch geplante Jobs zu ersetzen. Weitere Informationen finden Sie unter Verbesserungen bei JobScheduler.

Einschränkungen für Dienste im Hintergrund

Dienste, die im Hintergrund ausgeführt werden, können Geräteressourcen beanspruchen und so zu einer schlechteren Nutzererfahrung führen. Um dieses Problem zu vermeiden, gelten für Dienste eine Reihe von Einschränkungen.

Das System unterscheidet zwischen Apps im Vordergrund und Apps im Hintergrund. Die Definition des Hintergrunds für Diensteinschränkungen unterscheidet sich von der Definition, die für die Arbeitsspeicherverwaltung verwendet wird. Eine App kann im Hintergrund ausgeführt werden, was die Arbeitsspeicherverwaltung betrifft, aber im Vordergrund, was die Möglichkeit betrifft, Dienste zu starten. Eine App gilt als im Vordergrund, wenn einer der folgenden Punkte zutrifft:

  • Es gibt eine sichtbare Aktivität, unabhängig davon, ob die Aktivität gestartet oder pausiert ist.
  • Sie hat einen Dienst im Vordergrund.
  • Eine andere App im Vordergrund ist mit der App verbunden, entweder durch Bindung an einen ihrer Dienste oder durch Nutzung eines ihrer Inhaltsanbieter. Die App befindet sich beispielsweise im Vordergrund, wenn eine andere App an Folgendes gebunden ist:
    • IME
    • Hintergrunddienst
    • Benachrichtigungs-Listener
    • Sprach- oder SMS-Dienst

Wenn keine dieser Bedingungen erfüllt ist, wird die App als im Hintergrund ausgeführt betrachtet.

Wenn sich eine App im Vordergrund befindet, kann sie sowohl Dienste im Vordergrund als auch im Hintergrund erstellen und ausführen. Wenn eine App in den Hintergrund wechselt, hat sie mehrere Minuten Zeit, um weiterhin Dienste zu erstellen und zu verwenden. Am Ende dieses Zeitraums gilt die App als inaktiv. Zu diesem Zeitpunkt beendet das System die Hintergrunddienste der App, als hätte die App die Service.stopSelf()-Methoden der Dienste aufgerufen.

Unter bestimmten Umständen wird eine App im Hintergrund für einige Minuten auf eine temporäre Zulassungsliste gesetzt. Solange eine App auf der Zulassungsliste steht, kann sie Dienste uneingeschränkt starten und ihre Hintergrunddienste dürfen ausgeführt werden. Eine App wird auf die Zulassungsliste gesetzt, wenn sie eine Aufgabe ausführt, die für den Nutzer sichtbar ist, z. B.:

In vielen Fällen kann Ihre App Hintergrunddienste durch JobScheduler-Jobs ersetzen. Beispielsweise muss CoolPhotoApp prüfen, ob der Nutzer Fotos von Freunden erhalten hat, auch wenn die App nicht im Vordergrund ausgeführt wird. Bisher wurde in der App ein Hintergrunddienst verwendet, der den Cloud-Speicher der App abfragte. Für die Migration zu Android 8.0 (API-Level 26) ersetzt der Entwickler den Hintergrunddienst durch einen geplanten Job, der regelmäßig gestartet wird, den Server abfragt und dann beendet wird.

Vor Android 8.0 wurde ein Dienst im Vordergrund in der Regel so erstellt, dass zuerst ein Hintergrunddienst erstellt und dann in den Vordergrund verschoben wurde. Bei Android 8.0 gibt es eine Komplikation: Das System erlaubt es einer App im Hintergrund nicht, einen Hintergrunddienst zu erstellen. Aus diesem Grund wird in Android 8.0 die neue Methode startForegroundService() eingeführt, um einen neuen Dienst im Vordergrund zu starten. Nachdem das System den Dienst erstellt hat, hat die App fünf Sekunden Zeit, die Methode [startForeground()](/reference/android/app/Service#startForeground(int, android.app.Notification) des Dienstes aufzurufen, um die nutzersichtbare Benachrichtigung des neuen Dienstes anzuzeigen. Wenn die App nicht innerhalb des Zeitlimits startForeground() aufruft, beendet das System den Dienst und erklärt die App als ANR.

Einschränkungen bei Übertragungen

Wenn eine App sich für den Empfang von Übertragungen registriert, beansprucht der Empfänger der App jedes Mal Ressourcen, wenn die Übertragung gesendet wird. Dies kann zu Problemen führen, wenn sich zu viele Apps für den Empfang von Übertragungen registrieren, die auf Systemereignissen basieren. Ein Systemereignis, das eine Übertragung auslöst, kann dazu führen, dass alle diese Apps in schneller Folge Ressourcen verbrauchen, was die Nutzerfreundlichkeit beeinträchtigt. Um dieses Problem zu beheben, wurden in Android 7.0 (API-Level 24) Einschränkungen für Übertragungen eingeführt, wie unter Hintergrundoptimierung beschrieben. Unter Android 8.0 (API-Ebene 26) sind diese Einschränkungen noch strenger.

  • Bei Apps, die auf Android 8.0 oder höher ausgerichtet sind, können keine Übertragungsempfänger mehr für implizite Übertragungen im Manifest registriert werden, es sei denn, die Übertragung ist speziell auf diese App beschränkt. Ein impliziter Broadcast ist ein Broadcast, der nicht auf eine bestimmte Komponente in einer App ausgerichtet ist. Beispielsweise wird ACTION_PACKAGE_REPLACED an alle registrierten Listener in allen Apps gesendet, um sie darüber zu informieren, dass ein Paket auf dem Gerät ersetzt wurde. Da die Übertragung implizit ist, wird sie nicht an im Manifest registrierte Empfänger in Apps gesendet, die auf Android 8.0 oder höher ausgerichtet sind. ACTION_MY_PACKAGE_REPLACED ist ebenfalls eine implizite Übertragung. Da sie jedoch nur an die App gesendet wird, deren Paket ersetzt wurde, wird sie an im Manifest registrierte Empfänger gesendet.
  • Apps können sich weiterhin in ihren Manifesten für explizite Übertragungen registrieren.
  • Apps können Context.registerReceiver() zur Laufzeit verwenden, um einen Empfänger für beliebige Übertragungen zu registrieren, ob implizit oder explizit.
  • Übertragungen, für die eine Signaturberechtigung erforderlich ist, sind von dieser Einschränkung ausgenommen, da sie nur an Apps gesendet werden, die mit demselben Zertifikat signiert sind, nicht an alle Apps auf dem Gerät.

In vielen Fällen können Apps, die zuvor für eine implizite Übertragung registriert wurden, ähnliche Funktionen mithilfe eines JobScheduler-Jobs nutzen. Beispielsweise muss eine Foto-App in sozialen Netzwerken möglicherweise von Zeit zu Zeit Daten bereinigen und dies vorzugsweise tun, wenn das Gerät an ein Ladegerät angeschlossen ist. Bisher hat die App in ihrem Manifest einen Empfänger für ACTION_POWER_CONNECTED registriert. Wenn die App diese Übertragung empfing, wurde geprüft, ob eine Bereinigung erforderlich war. Für die Migration zu Android 8.0 oder höher entfernt die App diesen Empfänger aus ihrem Manifest. Stattdessen plant die App einen Bereinigungsjob, der ausgeführt wird, wenn das Gerät inaktiv ist und geladen wird.

Migrationsanleitung

Diese Änderungen wirken sich standardmäßig nur auf Apps aus, die auf Android 8.0 (API-Level 26) oder höher ausgerichtet sind. Nutzer können diese Einschränkungen jedoch auf dem Bildschirm Einstellungen für jede App aktivieren, auch wenn die App auf ein API-Level unter 26 ausgerichtet ist. Möglicherweise müssen Sie Ihre App aktualisieren, um die neuen Einschränkungen einzuhalten.

Prüfen Sie, wie Ihre App Dienste verwendet. Wenn Ihre App auf Diensten basiert, die im Hintergrund ausgeführt werden, während Ihre App inaktiv ist, müssen Sie sie ersetzen. Mögliche Lösungen:

  • Wenn Ihre App einen Dienst im Vordergrund erstellen muss, während sie im Hintergrund ausgeführt wird, verwenden Sie die Methode startForegroundService() anstelle von startService().
  • Wenn der Dienst für den Nutzer wahrnehmbar ist, machen Sie ihn zu einem Dienst im Vordergrund. Ein Dienst, der Audioinhalte wiedergibt, sollte beispielsweise immer ein Dienst im Vordergrund sein. Erstellen Sie den Dienst mit der Methode startForegroundService() anstelle von startService().
  • Finden Sie eine Möglichkeit, die Funktionalität des Dienstes mit einem geplanten Job zu duplizieren. Wenn der Dienst keine unmittelbar für den Nutzer wahrnehmbaren Aktionen ausführt, sollten Sie stattdessen in der Regel einen geplanten Job verwenden.
  • Verwenden Sie FCM, um Ihre App selektiv zu aktivieren, wenn Netzwerkereignisse auftreten, anstatt im Hintergrund zu Polling.
  • Hintergrundaktivitäten sollten erst ausgeführt werden, wenn die App im Vordergrund ist.

Prüfen Sie die im Manifest Ihrer App definierten Broadcast-Empfänger. Wenn dein Manifest einen Empfänger für eine betroffene implizite Übertragung deklariert, musst du ihn ersetzen. Mögliche Lösungen:

  • Erstellen Sie den Empfänger zur Laufzeit, indem Sie Context.registerReceiver() aufrufen, anstatt ihn im Manifest zu deklarieren.
  • Verwenden Sie einen geplanten Job, um die Bedingung zu prüfen, die die implizite Übertragung ausgelöst hätte.