Einschränkungen bei der Hintergrundausführung

Immer wenn eine App im Hintergrund ausgeführt wird, verbraucht sie einige der begrenzten Ressourcen des Geräts, z. B. den RAM. Dies kann die Nutzung beeinträchtigen, insbesondere wenn der Nutzer eine ressourcenintensive App verwendet, z. B. ein Spiel oder ein Video ansehen. Um die Nutzerfreundlichkeit zu verbessern, schränkt Android 8.0 (API-Level 26) die Aktionen von Apps ein, die im Hintergrund ausgeführt werden. In diesem Dokument werden die Änderungen am Betriebssystem beschrieben. Außerdem erfahren Sie, wie Sie Ihre Anwendung aktualisieren können, damit sie unter Berücksichtigung der neuen Einschränkungen einwandfrei funktioniert.

Übersicht

Viele Android-Apps und -Dienste können gleichzeitig ausgeführt werden. Ein Nutzer könnte beispielsweise in einem Fenster ein Spiel spielen, während er in einem anderen Fenster im Web surft, und eine dritte App zum Abspielen von Musik verwenden. Je mehr Anwendungen gleichzeitig ausgeführt werden, desto stärker wird das System belastet. Wenn zusätzliche Anwendungen oder Dienste im Hintergrund ausgeführt werden, wird das System dadurch zusätzlich belastet, was zu einer schlechten Nutzererfahrung führen kann, z. B. wenn die Musik-App plötzlich heruntergefahren wird.

Um das Risiko dieser Probleme zu verringern, beschränkt Android 8.0 die Aktionen von Apps, wenn Nutzer nicht direkt mit ihnen interagieren. Für Apps gibt es zwei Einschränkungen:

  • Einschränkungen der Hintergrunddienste: Wenn eine Anwendung inaktiv ist, gelten Einschränkungen für die Nutzung von Hintergrunddiensten. Dies gilt nicht für Dienste im Vordergrund, die für den Nutzer stärker wahrgenommen werden.

  • Übertragungsbeschränkungen: Mit wenigen Ausnahmen können Apps ihr Manifest nicht verwenden, um sich für implizite Broadcasts zu registrieren. Sie können sich trotzdem zur Laufzeit für diese Broadcasts registrieren und das Manifest verwenden, um sich für explizite Broadcasts und Broadcasts zu registrieren, die speziell auf ihre App ausgerichtet sind.

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

Einschränkungen der Hintergrunddienste

Dienste, die im Hintergrund ausgeführt werden, können Geräteressourcen verbrauchen, was die Nutzerfreundlichkeit beeinträchtigen kann. Um dieses Problem zu beheben, wendet das System eine Reihe von Einschränkungen bei Diensten an.

Das System unterscheidet zwischen Apps im Vordergrund und Hintergrund. Die Definition des Hintergrunds zum Zweck von Diensteinschränkungen unterscheidet sich von der Definition, die von der Arbeitsspeicherverwaltung verwendet wird. Eine Anwendung kann im Hintergrund der Speicherverwaltung ausgeführt werden, im Vordergrund jedoch bezüglich der Möglichkeit, Dienste zu starten. Eine App wird als im Vordergrund ausgeführt, wenn eine der folgenden Bedingungen zutrifft:

  • Es ist eine sichtbare Aktivität zu sehen, unabhängig davon, ob die Aktivität gestartet oder pausiert wurde.
  • Es hat einen Dienst im Vordergrund.
  • Eine andere App im Vordergrund ist mit der App verbunden, entweder über eine Bindung an einen ihrer Dienste oder über einen ihrer Contentanbieter. Das ist beispielsweise der Fall, wenn eine andere App an Folgendes gebunden wird:
    • IME
    • Hintergrundservice
    • Benachrichtigungs-Listener
    • Sprach- oder SMS-Dienst

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

Während eine App im Vordergrund ausgeführt wird, können Dienste im Vordergrund und Hintergrund frei erstellt und ausgeführt werden. Wenn eine App in den Hintergrund versetzt wird, hat sie ein Fenster von mehreren Minuten, in dem sie noch Dienste erstellen und verwenden darf. Am Ende des Fensters gilt die App als inaktiv. Zu diesem Zeitpunkt beendet das System die Hintergrunddienste der App, so als hätte die App die Service.stopSelf()-Methoden der Dienste aufgerufen.

Unter bestimmten Umständen wird eine Hintergrund-App für einige Minuten auf eine temporäre Zulassungsliste gesetzt. Eine App auf der Zulassungsliste kann Dienste ohne Einschränkung starten und ihre Hintergrunddienste dürfen ausgeführt werden. Eine Anwendung wird auf die Zulassungsliste gesetzt, wenn sie eine für den Nutzer sichtbare Aufgabe ausführt, z. B.:

In vielen Fällen kann Ihre App Hintergrunddienste durch JobScheduler-Jobs ersetzen. Cool PhotoApp muss beispielsweise prüfen, ob der Nutzer geteilte Fotos von Freunden erhalten hat, auch wenn die App nicht im Vordergrund ausgeführt wird. Zuvor hat die Anwendung einen Hintergrunddienst verwendet, der den Cloud-Speicher der Anwendung überprüft hat. Bei der 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 den Dienst beendet.

Vor Android 8.0 wurde ein Dienst im Vordergrund normalerweise erstellt, indem ein Hintergrunddienst erstellt und dieser Dienst dann im Vordergrund hochgestuft wurde. Unter Android 8.0 gibt es eine Komplikation: Das System lässt nicht zu, dass eine Hintergrund-App einen Hintergrunddienst erstellt. 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 für Nutzer sichtbare Benachrichtigung des neuen Dienstes anzuzeigen. Wenn die App startForeground() innerhalb des Zeitlimits nicht aufruft, stoppt das System den Dienst und gibt für die App einen ANR-Fehler an.

Übertragungseinschränkungen

Wenn sich eine Anwendung für den Empfang von Broadcasts registriert, verbraucht der Empfänger der Anwendung bei jedem Senden Ressourcen. Dies kann zu Problemen führen, wenn sich zu viele Apps für den Empfang von Broadcasts registrieren, die auf Systemereignissen basieren. Ein Systemereignis, das einen Broadcast auslöst, kann dazu führen, dass alle diese Apps in kurzer Abfolge Ressourcen verbrauchen, was die Nutzererfahrung beeinträchtigt. Um dieses Problem zu beheben, wurden von Android 7.0 (API-Level 24) Einschränkungen für Broadcasts eingeführt, wie unter Hintergrundoptimierung beschrieben. Unter Android 8.0 (API-Level 26) gelten strengere Einschränkungen.

  • Apps, die auf Android 8.0 oder höher ausgerichtet sind, können in ihrem Manifest keine Übertragungsempfänger mehr für implizite Broadcasts registrieren, es sei denn, die Übertragung ist ausdrücklich auf diese App beschränkt. Eine implizite Übertragung ist eine Übertragung, die nicht auf eine bestimmte Komponente innerhalb einer App ausgerichtet ist. ACTION_PACKAGE_REPLACED wird beispielsweise an alle registrierten Listener in allen Apps gesendet und informiert diese darüber, dass ein Paket auf dem Gerät ersetzt wurde. Da der Broadcast implizit ist, wird er in Apps, die auf Android 8.0 oder höher ausgerichtet sind, nicht an Manifest-registrierte Empfänger gesendet. ACTION_MY_PACKAGE_REPLACED ist ebenfalls ein impliziter Broadcast. Da er jedoch nur an die App gesendet wird, deren Paket ersetzt wurde, wird er an Manifest-registrierte Empfänger gesendet.
  • Apps können weiterhin in ihren Manifesten für explizite Broadcasts registriert werden.
  • Anwendungen können Context.registerReceiver() zur Laufzeit verwenden, um einen Empfänger für Broadcasts zu registrieren, unabhängig davon, ob sie implizit oder explizit sind.
  • Broadcasts, die eine Signaturberechtigung erfordern, sind von dieser Einschränkung ausgenommen, da sie nur an Apps gesendet werden, die mit demselben Zertifikat signiert sind, und nicht an alle Apps auf dem Gerät.

In vielen Fällen können Apps, die zuvor für einen impliziten Broadcast registriert wurden, durch die Verwendung eines JobScheduler-Jobs ähnliche Funktionen erhalten. Beispielsweise kann es sein, dass eine Social-Foto-App von Zeit zu Zeit Daten bereinigen muss und dies bevorzugt, 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 diesen Broadcast empfangen hat, wird geprüft, ob eine Bereinigung erforderlich ist. Zur Migration zu Android 8.0 oder höher wird der Empfänger aus dem Manifest der App entfernt. Stattdessen plant die App einen Bereinigungsjob, der ausgeführt wird, wenn das Gerät inaktiv ist und aufgeladen wird.

Migrationsanleitung

Standardmäßig betreffen diese Änderungen nur Apps, 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 zu erfüllen.

Überprüfen Sie, wie Ihre App Dienste verwendet. Wenn Ihre Anwendung Dienste benötigt, die im Hintergrund ausgeführt werden, während die Anwendung inaktiv ist, müssen Sie diese 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 sichtbar ist, machen Sie ihn zu einem Dienst im Vordergrund. Ein Dienst, der Audio abspielt, sollte beispielsweise immer ein Dienst im Vordergrund sein. Erstellen Sie den Dienst mit der Methode startForegroundService() anstelle von startService().
  • Suchen Sie nach einer Möglichkeit, die Funktionen des Dienstes mit einem geplanten Auftrag zu duplizieren. Wenn der Dienst keine für den Nutzer sofort erkennbare Aktion ausführt, sollten Sie im Allgemeinen stattdessen einen geplanten Job verwenden können.
  • Verwenden Sie FCM, um den Ruhemodus Ihrer Anwendung bei Netzwerkereignissen selektiv zu beenden, anstatt sie im Hintergrund abzufragen.
  • Hintergrundarbeit aufschieben, bis die Anwendung natürlich im Vordergrund zu sehen ist

Prüfe die im Manifest deiner App festgelegten Broadcast-Empfänger. Wenn in Ihrem Manifest ein Empfänger für eine betroffene implizite Übertragung deklariert ist, müssen Sie diesen ersetzen. Mögliche Lösungen:

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