Neben neuen Funktionen und Funktionen beinhaltet Android 8.0 (API-Level 26) eine Vielzahl von System- und API-Verhaltensänderungen. In diesem Dokument werden einige der wichtigsten Änderungen beschrieben, die Sie bei Ihren Anwendungen berücksichtigen und verstehen sollten.
Die meisten dieser Änderungen wirken sich auf alle Apps aus, unabhängig davon, auf welche Android-Version sie ausgerichtet sind. Einige Änderungen betreffen jedoch nur Apps, die auf Android 8.0 ausgerichtet sind. Für bessere Übersicht ist diese Seite in zwei Abschnitte unterteilt: Änderungen für alle Apps und Änderungen für Apps, die auf Android 8.0 ausgerichtet sind.
Änderungen für alle Apps
Diese Verhaltensänderungen gelten für
Einschränkungen bei der Hintergrundausführung
Eine der Änderungen, die in Android 8.0 (API-Level 26) eingeführt wird, um die Akkulaufzeit zu verlängern. Wenn deine App in den Status im Cache gespeichert wird und keine aktiven Komponenten hat, gibt das System alle Wakelocks aus, die in der App vorhanden sind.
Zur Verbesserung der Geräteleistung schränkt das System außerdem bestimmte Verhaltensweisen von Apps ein, die nicht im Vordergrund ausgeführt werden. Im Detail:
- Der Zugriff von Apps, die im Hintergrund ausgeführt werden, auf Hintergrunddienste ist jetzt eingeschränkt.
- Apps können sich nicht über ihre Manifeste für die meisten impliziten Übertragungen registrieren, d. h. Übertragungen, die nicht speziell auf die App ausgerichtet sind.
Standardmäßig gelten diese Einschränkungen nur für Apps, die auf O ausgerichtet sind. Nutzer können diese Einschränkungen jedoch über den Bildschirm Einstellungen für jede App aktivieren, auch wenn die App nicht auf O ausgerichtet ist.
Android 8.0 (API-Ebene 26) enthält außerdem die folgenden Änderungen an bestimmten Methoden:
- Die Methode
startService()
löst jetzt eineIllegalStateException
aus, wenn eine App, die auf Android 8.0 ausgerichtet ist, versucht, diese Methode in einer Situation zu verwenden, in der das Erstellen von Hintergrunddiensten nicht zulässig ist. - Mit der neuen Methode
Context.startForegroundService()
wird ein Dienst im Vordergrund gestartet. Das System ermöglicht es Apps,Context.startForegroundService()
auch dann aufzurufen, wenn die App im Hintergrund ausgeführt wird. Die Anwendung muss jedoch die MethodestartForeground()
dieses Dienstes innerhalb von fünf Sekunden nach dem Erstellen des Dienstes aufrufen.
Weitere Informationen finden Sie unter Limits für die Ausführung im Hintergrund.
Einschränkungen bei der Standortermittlung im Hintergrund unter Android
Um den Akku zu schonen, die Nutzerfreundlichkeit zu verbessern und die Systemintegrität zu erhalten, erhalten Hintergrund-Apps auf Geräten mit Android 8.0 seltener Standortaktualisierungen. Diese Verhaltensänderung betrifft alle Apps, die Standortupdates erhalten, einschließlich der Google Play-Dienste.
Diese Änderungen betreffen die folgenden APIs:
- Anbieter für kombinierte Standortbestimmung (Fused Location Provider, FLP)
- Geofencing
- GNSS-Messungen
- Standortmanager
- WLAN-Manager
Führen Sie die folgenden Schritte aus, damit Ihre App wie erwartet ausgeführt wird:
- Prüfen Sie die Logik Ihrer App und achten Sie darauf, dass Sie die neuesten Standort-APIs verwenden.
- Testen Sie, ob Ihre App das Verhalten aufweist, das Sie für jeden Anwendungsfall erwarten.
- Für Anwendungsfälle, die vom aktuellen Standort des Nutzers abhängen, kannst du den Anbieter für kombinierte Standortbestimmung oder Geofencing nutzen.
Weitere Informationen zu diesen Änderungen finden Sie unter Einschränkungen für die Standortermittlung im Hintergrund.
App-Verknüpfungen
Android 8.0 (API-Level 26) enthält die folgenden Änderungen an App-Verknüpfungen:
- Die
com.android.launcher.action.INSTALL_SHORTCUT
-Ausstrahlung hat keine Auswirkungen mehr auf Ihre App, da es sich jetzt um eine private, implizite Ausstrahlung handelt. Stattdessen sollten Sie eine App-Verknüpfung mit der MethoderequestPinShortcut()
aus der KlasseShortcutManager
erstellen. - Der Intent
ACTION_CREATE_SHORTCUT
kann jetzt App-Verknüpfungen erstellen, die Sie mithilfe der KlasseShortcutManager
verwalten. Mit diesem Intent können auch alte Launcher-Verknüpfungen erstellt werden, die nicht mitShortcutManager
interagieren. Bisher konnten mit dieser Intent-Art nur alte Launcher-Verknüpfungen erstellt werden. - Verknüpfungen, die mit
requestPinShortcut()
erstellt wurden, und Verknüpfungen, die in einer Aktivität erstellt wurden, die denACTION_CREATE_SHORTCUT
-Intent verarbeitet, sind jetzt vollwertige App-Verknüpfungen. Apps können sie jetzt mit den Methoden inShortcutManager
aktualisieren. - Alte Verknüpfungen behalten ihre Funktionen aus früheren Android-Versionen, aber du musst sie in deiner App manuell in App-Verknüpfungen konvertieren.
Weitere Informationen zu den Änderungen an App-Verknüpfungen finden Sie im Hilfeartikel Verknüpfungen und Widgets anpinnen.
Sprachen und Internationalisierung
Mit Android 7.0 (API-Level 24) wurde das Konzept eingeführt, dass ein standardmäßiges Kategoriegebietsschema angegeben werden kann. Einige APIs verwenden jedoch weiterhin die generische Locale.getDefault()
-Methode ohne Argumente, obwohl sie stattdessen die Standardeinstellung der Kategorie DISPLAY
hätten verwenden sollen. Unter Android 8.0 (API-Ebene 26) wird für die folgenden Methoden jetzt Locale.getDefault(Category.DISPLAY)
anstelle von Locale.getDefault()
verwendet:
Locale.getDisplayScript(Locale)
greift auch auf Locale.getDefault()
zurück, wenn der für das Argument Locale
angegebene displayScript-Wert nicht verfügbar ist.
Weitere Änderungen im Zusammenhang mit Sprachen und Internationalisierung:
- Beim Aufrufen von
Currency.getDisplayName(null)
wird eineNullPointerException
geworfen, was dem dokumentierten Verhalten entspricht. - Das Parsen des Zeitzonennamens hat sich geändert. Früher haben Android-Geräte den Wert der Systemuhr verwendet, der beim Booten erfasst wurde, um die Zeitzonennamen im Cache zu speichern, die zum Parsen von Datums- und Uhrzeitangaben verwendet wurden. Daher kann das Parsen beeinträchtigt werden, wenn die Systemuhr beim Starten falsch war oder in anderen, selteneren Fällen.
In den meisten Fällen verwendet die Parselogik beim Parsen von Zeitzonennamen ICU und den Wert der aktuellen Systemuhr. Durch diese Änderung werden genauere Ergebnisse erzielt, die sich von früheren Android-Versionen unterscheiden können, wenn Ihre App Klassen wie
SimpleDateFormat
verwendet. - Unter Android 8.0 (API-Ebene 26) wird die ICU-Version auf Version 58 aktualisiert.
Benachrichtigungsfenster
Wenn eine App die Berechtigung SYSTEM_ALERT_WINDOW
verwendet und versucht, mit einem der folgenden Fenstertypen Benachrichtigungsfenster über anderen Apps und Systemfenstern anzuzeigen:
...werden diese Fenster immer unter den Fenstern angezeigt, für die der Fenstertyp TYPE_APPLICATION_OVERLAY
verwendet wird. Wenn eine App auf Android 8.0 (API-Level 26) ausgerichtet ist, verwendet sie den Fenstertyp TYPE_APPLICATION_OVERLAY
zum Anzeigen von Benachrichtigungsfenstern.
Weitere Informationen finden Sie im Abschnitt Gängige Fenstertypen für Benachrichtigungsfenster der Verhaltensänderungen für Apps, die auf Android 8.0 ausgerichtet sind.
Eingabe und Navigation
Mit der Einführung von Android-Apps auf ChromeOS und anderen großen Geräten wie Tablets wird die Tastaturnavigation in Android-Apps immer beliebter. In Android 8.0 (API-Level 26) haben wir die Verwendung der Tastatur als Navigationseingabegerät geändert, was zu einem zuverlässigeren, vorhersehbaren Modell für die pfeil- und tabulatorbasierte Navigation führt.
Insbesondere haben wir die folgenden Änderungen am Verhalten des Elementfokus vorgenommen:
-
Wenn Sie keine Farben für den Fokusstatus für ein
View
-Objekt (entweder für den Vordergrund oder den Hintergrund) definiert haben, legt das Framework jetzt eine Standard-Fokus-Hervorhebungsfarbe für dasView
fest. Dieses Fokus-Highlight ist ein Wellenmuster, das auf dem Thema der Aktivität basiert.Wenn Sie nicht möchten, dass ein
View
-Objekt dieses Standard-Highlight verwendet, wenn es den Fokus erhält, legen Sie in der Layout-XML-Datei mit demView
das Attributandroid:defaultFocusHighlightEnabled
auffalse
fest oder geben Siefalse
in der UI-Logik Ihrer App ansetDefaultFocusHighlightEnabled()
weiter. - Wenn Sie testen möchten, wie sich die Tastatureingabe auf den Fokus von UI-Elementen auswirkt, können Sie die Entwickleroption Zeichnen > Layoutgrenzen anzeigen aktivieren. Unter Android 8.0 wird bei dieser Option über dem Element, das derzeit den Fokus hat, ein „X“-Symbol angezeigt.
Außerdem sind alle Symbolleistenelemente in Android 8.0 automatisch Tastaturnavigationscluster, was die Navigation in und aus den einzelnen Symbolleisten insgesamt erleichtert.
Weitere Informationen dazu, wie Sie die Unterstützung für die Tastaturnavigation in Ihrer App verbessern können, finden Sie im Leitfaden Tastaturnavigation unterstützen.
Autofill für Webformulare
Da das Autofill-Framework von Android jetzt eine integrierte Unterstützung für die Autofill-Funktion bietet, haben sich die folgenden Methoden im Zusammenhang mit WebView
-Objekten für Apps geändert, die auf Geräten mit Android 8.0 (API-Ebene 26) installiert sind:
WebSettings
-
- Die Methode
getSaveFormData()
gibt jetztfalse
zurück. Bisher wurde stattdessentrue
zurückgegeben. - Das Anrufen von
setSaveFormData()
hat keine Auswirkungen mehr.
- Die Methode
WebViewDatabase
-
- Das Anrufen von
clearFormData()
hat keine Auswirkungen mehr. - Die Methode
hasFormData()
gibt jetztfalse
zurück. Bisher wurde mit dieser Methodetrue
zurückgegeben, wenn das Formular Daten enthielt.
- Das Anrufen von
Bedienungshilfen
Android 8.0 (API-Level 26) enthält die folgenden Änderungen an der Barrierefreiheit:
-
Das Framework für Barrierefreiheit wandelt jetzt alle Doppeltippen in
ACTION_CLICK
-Aktionen um. Dadurch verhält sich TalkBack ähnlich wie andere Bedienungshilfen.Wenn für die
View
-Objekte Ihrer App eine benutzerdefinierte Touchbedienung verwendet wird, sollten Sie prüfen, ob sie weiterhin mit TalkBack funktionieren. Möglicherweise müssen Sie nur den Klick-Handler registrieren, der von IhrenView
-Objekten verwendet wird. Wenn TalkBack die an diesenView
-Objekten ausgeführten Touch-Gesten immer noch nicht erkennt, überschreiben SieperformAccessibilityAction()
. - Dienste zur Barrierefreiheit erkennen jetzt alle
ClickableSpan
-Instanzen in denTextView
-Objekten Ihrer App.
Weitere Informationen zur Verbesserung der Barrierefreiheit Ihrer App finden Sie unter Bedienungshilfen.
Netzwerke und HTTP(S)-Konnektivität
Android 8.0 (API-Level 26) enthält die folgenden Verhaltensänderungen bei Netzwerk- und HTTP(S)-Verbindungen:
- OPTIONS-Anfragen ohne Textkörper haben einen
Content-Length: 0
-Header. Bisher gab es keinenContent-Length
-Header. - HttpURLConnection normalisiert URLs mit leeren Pfaden, indem nach dem Host- oder Autoritätsnamen ein Schrägstrich angehängt wird. Beispielsweise wird
http://example.com
inhttp://example.com/
konvertiert. - Eine benutzerdefinierte Proxy-Auswahl, die über ProxySelector.setDefault() festgelegt wird, richtet sich nur an die Adresse (Schema, Host und Port) einer angeforderten URL. Daher basiert die Proxy-Auswahl möglicherweise nur auf diesen Werten. Eine URL, die an einen benutzerdefinierten Proxy-Selektor übergeben wird, enthält weder den Pfad noch die Abfrageparameter oder Fragmente der angeforderten URL.
- URIs dürfen keine leeren Labels enthalten.
Bisher unterstützte die Plattform eine Umgehung, um leere Labels in Hostnamen zuzulassen, was eine unzulässige Verwendung von URIs darstellt. Diese Umgehung diente der Kompatibilität mit älteren libcore-Releases. Wenn Entwickler die API falsch verwenden, wird eine ADB-Nachricht angezeigt: „Der URI beispiel.de hat leere Labels im Hostnamen. Dieser ist fehlerhaft und wird in zukünftigen Android-Releases nicht akzeptiert.“ Diese Umgehung ist in Android 8.0 nicht mehr möglich. Das System gibt für fehlerhafte URIs den Wert „null“ zurück.
- Die Implementierung von HttpsURLConnection in Android 8.0 führt kein Fallback auf eine unsichere Version des TLS/SSL-Protokolls durch.
- Die Verarbeitung von Tunneling-HTTP(S)-Verbindungen wurde wie folgt geändert:
- Beim Tunneling einer HTTPS-Verbindung über eine Verbindung fügt das System die Portnummer (:443) korrekt in die Host-Zeile ein, wenn diese Informationen an einen zwischengeschalteten Server gesendet werden. Bisher wurde die Portnummer nur in der CONNECT-Zeile angegeben.
- Das System sendet keine User-Agent- und Proxy-Autorisierungsheader mehr aus einer getunnelten Anfrage an den Proxyserver.
Das System sendet beim Einrichten des Tunnels keinen Proxy-Autorisierungsheader mehr für eine getunnelte Http(s)URLConnection an den Proxy. Stattdessen generiert das System einen Proxy-Autorisierungs-Header und sendet ihn an den Proxy, wenn dieser als Antwort auf die ursprüngliche Anfrage HTTP 407 sendet.
Ebenso wird der User-Agent-Header nicht mehr aus der getunnelten Anfrage in die Proxyanfrage kopiert, mit der der Tunnel eingerichtet wird. Stattdessen generiert die Bibliothek einen User-Agent-Header für diese Anfrage.
- Die Methode
send(java.net.DatagramPacket)
wirft eine SocketException, wenn die zuvor ausgeführte connect()-Methode fehlgeschlagen ist.- DatagramSocket.connect() setzt eine pendingSocketException, wenn ein interner Fehler auftritt. Vor Android 8.0 wurde bei einem nachfolgenden recv()-Aufruf eine SocketException geworfen, auch wenn ein send()-Aufruf erfolgreich gewesen wäre. Aus Gründen der Einheitlichkeit wird bei beiden Aufrufen jetzt eine SocketException geworfen.
- InetAddress.isReachable() versucht, ICMP zu verwenden, bevor es zum TCP-Echo-Protokoll zurückkehrt.
- Einige Hosts, die Port 7 (TCP-Echo) blockieren, z. B. google.com, sind jetzt möglicherweise erreichbar, wenn sie das ICMP-Echo-Protokoll akzeptieren.
- Bei wirklich nicht erreichbaren Hosts bedeutet diese Änderung, dass doppelt so viel Zeit vergeht, bis der Aufruf zurückgegeben wird.
Bluetooth
Unter Android 8.0 (API-Ebene 26) werden die folgenden Änderungen an der Länge der Daten vorgenommen, die mit der ScanRecord.getBytes()
-Methode abgerufen werden:
- Die Methode
getBytes()
macht keine Annahmen in Bezug auf die Anzahl der empfangenen Byte. Daher sollten Anwendungen nicht von einer Mindest- oder Höchstanzahl zurückgegebener Byte abhängig sein. Stattdessen sollte die Länge des resultierenden Arrays ausgewertet werden. - Bluetooth 5-kompatible Geräte können eine Datenlänge zurückgeben, die über dem bisherigen Maximum von etwa 60 Byte liegt.
- Wenn ein Remote-Gerät keine Scanantwort zurückgibt, werden möglicherweise auch weniger als 60 Byte zurückgegeben.
Nahtlose Konnektivität
Unter Android 8.0 (API-Level 26) wurden eine Reihe von Verbesserungen an den WLAN-Einstellungen vorgenommen, um die Auswahl des WLANs zu vereinfachen, das die beste Nutzererfahrung bietet. Zu den Änderungen gehören:
- Verbesserte Stabilität und Zuverlässigkeit
- Eine intuitivere Benutzeroberfläche
- Ein einziges, konsolidiertes Menü für WLAN-Einstellungen.
- Auf kompatiblen Geräten wird WLAN automatisch aktiviert, wenn sich ein gespeichertes Netzwerk mit hoher Qualität in der Nähe befindet.
Sicherheit
Android 8.0 enthält die folgenden sicherheitsrelevanten Änderungen:
- SSLv3 wird von dieser Plattform nicht mehr unterstützt.
- Beim Herstellen einer HTTPS-Verbindung zu einem Server, der die TLS-Protokollversion falsch implementiert, versucht
HttpsURLConnection
nicht mehr, auf frühere TLS-Protokollversionen umzustellen und es noch einmal zu versuchen. - Unter Android 8.0 (API-Ebene 26) wird ein SECCOMP-Filter (Secure Computing) auf alle Apps angewendet. Die Liste der zulässigen Syscalls ist auf die durch Bioonic bereitgestellten beschränkt. Es gibt zwar mehrere andere Systemaufrufe zur Abwärtskompatibilität, wir empfehlen jedoch, diese nicht zu verwenden.
- Die
WebView
-Objekte Ihrer App werden jetzt im Mehrprozessmodus ausgeführt. Webinhalte werden in einem separaten, vom Prozess der App getrennten Prozess verarbeitet, um die Sicherheit zu erhöhen. -
Sie können nicht mehr davon ausgehen, dass sich APKs in Verzeichnissen befinden, deren Namen auf -1 oder -2 enden. Anwendungen sollten zum Abrufen des Verzeichnisses
sourceDir
verwenden und nicht direkt das Verzeichnisformat verwenden. - Informationen zu Sicherheitsverbesserungen im Zusammenhang mit der Verwendung nativer Bibliotheken finden Sie unter Native Bibliotheken.
Außerdem werden mit Android 8.0 (API-Ebene 26) die folgenden Änderungen in Bezug auf die Installation unbekannter Apps aus unbekannten Quellen eingeführt:
- Der Wert der bisherigen Einstellung
INSTALL_NON_MARKET_APPS
ist jetzt immer „1“. Wenn Sie feststellen möchten, ob eine unbekannte Quelle Apps über den Paketinstallationsprogramm installieren kann, sollten Sie stattdessen den Rückgabewert voncanRequestPackageInstalls()
verwenden. - Wenn Sie versuchen, den Wert von
INSTALL_NON_MARKET_APPS
mitsetSecureSetting()
zu ändern, wirdUnsupportedOperationException
ausgelöst. Wenn Sie verhindern möchten, dass Nutzer unbekannte Apps über unbekannte Quellen installieren, sollten Sie stattdessen die NutzereinschränkungDISALLOW_INSTALL_UNKNOWN_SOURCES
anwenden. -
Bei verwalteten Profilen, die auf Geräten mit Android 8.0 (API-Ebene 26) erstellt wurden, ist die Nutzereinschränkung
DISALLOW_INSTALL_UNKNOWN_SOURCES
automatisch aktiviert. Für vorhandene verwaltete Profile auf Geräten mit einem Upgrade auf Android 8.0 wird dieDISALLOW_INSTALL_UNKNOWN_SOURCES
Nutzerbeschränkung automatisch aktiviert, es sei denn, der Profilinhaber hat diese Einschränkung (vor dem Upgrade) explizit deaktiviert, indemINSTALL_NON_MARKET_APPS
auf 1 gesetzt wurde.
Weitere Informationen zur Installation unbekannter Apps finden Sie im Leitfaden Berechtigungen zur Installation unbekannter Apps.
Weitere Richtlinien zur Erhöhung der Sicherheit Ihrer App finden Sie unter Sicherheit für Android-Entwickler.
Datenschutz
Mit Android 8.0 (API-Level 26) werden die folgenden datenschutzbezogenen Änderungen an der Plattform vorgenommen.
- Die Plattform behandelt Kennungen jetzt anders.
-
Bei Apps, die vor einem Over-the-air-Update auf eine Version von Android 8.0 (API-Level 26) installiert wurden, bleibt der Wert von
ANDROID_ID
unverändert, es sei denn, die App wird nach dem Over-the-air-Update deinstalliert und dann wieder installiert. Damit die Werte auch bei Deinstallationen nach dem Over-the-air-Update beibehalten werden, können Entwickler die alten und neuen Werte mithilfe der Schlüssel-/Wert-Sicherung verknüpfen. - Für Apps, die auf Geräten mit Android 8.0 installiert sind, wird der Wert von
ANDROID_ID
jetzt pro App-Signaturschlüssel und Nutzer festgelegt. Der Wert vonANDROID_ID
ist für jede Kombination aus App-Signaturschlüssel, Nutzer und Gerät eindeutig. Daher sehen Apps mit unterschiedlichen Signaturschlüsseln, die auf demselben Gerät ausgeführt werden, nicht mehr dieselbe Android-ID (auch nicht für denselben Nutzer). - Der Wert von
ANDROID_ID
ändert sich bei der Deinstallation oder Neuinstallation des Pakets nicht, solange der Signaturschlüssel derselbe ist (und die App nicht vor einem OTA-Update für eine Version von Android 8.0 installiert wurde). - Der Wert von
ANDROID_ID
ändert sich nicht, auch wenn sich der Schlüssel für die Paketsignatur durch ein Systemupdate ändert. - Auf Geräten, die mit Google Play-Diensten und der Werbe-ID ausgeliefert werden, müssen Sie die
Werbe-ID verwenden. Ein einfaches, standardmäßiges System zur Monetarisierung von Apps.
Die Werbe-ID ist eine eindeutige ID für Werbezwecke, die vom Nutzer zurückgesetzt werden kann. Sie wird von den Google Play-Diensten bereitgestellt.
Andere Gerätehersteller sollten
ANDROID_ID
weiterhin anbieten.
-
Bei Apps, die vor einem Over-the-air-Update auf eine Version von Android 8.0 (API-Level 26) installiert wurden, bleibt der Wert von
- Die Abfrage der Systemeigenschaft
net.hostname
ergibt ein Nullergebnis.
Protokollierung nicht abgefangener Ausnahmen
Wenn eine App eine Thread.UncaughtExceptionHandler
installiert, die nicht den Standard-Thread.UncaughtExceptionHandler
aufruft, wird die App vom System nicht beendet, wenn eine nicht abgefangene Ausnahme auftritt. Ab Android 8.0 (API-Level 26) protokolliert das System in dieser Situation den Stacktrace der Ausnahme. In früheren Versionen der Plattform wurde der Stacktrace der Ausnahme nicht protokolliert.
Wir empfehlen, dass benutzerdefinierte Thread.UncaughtExceptionHandler
-Implementierungen immer den Standard-Handler aufrufen. Apps, die dieser Empfehlung folgen, sind von der Änderung in Android 8.0 nicht betroffen.
Änderung der Signatur von findViewById()
Alle Instanzen der findViewById()
-Methode geben jetzt
<T extends View> T
anstelle von View
zurück. Diese Änderung hat folgende Auswirkungen:
- Dies kann dazu führen, dass vorhandener Code nun einen mehrdeutigen Rückgabetyp hat, z. B. wenn sowohl
someMethod(View)
als auchsomeMethod(TextView)
vorhanden sind, das das Ergebnis eines Aufrufs vonfindViewById()
annimmt. - Bei Verwendung der Java 8-Quellsprache ist ein expliziter Cast zu
View
erforderlich, wenn der Rückgabetyp nicht eingeschränkt ist (z. B.assertNotNull(findViewById(...)).someViewMethod())
). - Bei Überschreibungen nicht abschließender
findViewById()
-Methoden (z. B.Activity.findViewById()
) muss der Rückgabetyp aktualisiert werden.
Änderung der Nutzungsstatistiken des Kontaktanbieters
In früheren Android-Versionen können Entwickler mithilfe der Komponente „Kontakteanbieter“ Nutzungsdaten für jeden Kontakt abrufen. Diese Nutzungsdaten enthalten Informationen zu jeder E-Mail-Adresse und Telefonnummer, die mit einem Kontakt verknüpft sind, einschließlich der Häufigkeit, mit der der Kontakt kontaktiert wurde, und des letzten Kontakts. Apps, die die Berechtigung READ_CONTACTS
anfordern, können diese Daten lesen.
Apps können diese Daten weiterhin lesen, wenn sie die Berechtigung READ_CONTACTS
anfordern. Unter Android 8.0 (API-Ebene 26) und höher werden bei Abfragen von Nutzungsdaten keine genauen Werte, sondern Näherungswerte zurückgegeben. Die genauen Werte werden intern im Android-System verwaltet. Diese Änderung hat daher keine Auswirkungen auf die Autocomplete API.
Diese Verhaltensänderung betrifft die folgenden Abfrageparameter:
Umgang mit Datenerhebung
AbstractCollection.removeAll()
und AbstractCollection.retainAll()
werfen jetzt immer eine NullPointerException
; zuvor wurde die NullPointerException
nicht geworfen, wenn die Sammlung leer war. Durch diese Änderung entspricht das Verhalten der Dokumentation.
Android Enterprise
Unter Android 8.0 (API-Level 26) ändert sich das Verhalten einiger APIs und Funktionen für Unternehmens-Apps, einschließlich Device Policy Controllers (DPCs). Zu den Änderungen gehören:
- Neue Verhaltensweisen, damit Apps Arbeitsprofile auf vollständig verwalteten Geräten unterstützen.
- Änderungen an der Verarbeitung von Systemupdates, der App-Überprüfung und der Authentifizierung, um die Geräte- und Systemintegrität zu erhöhen.
- Verbesserungen bei der Nutzerfreundlichkeit bei Bereitstellung, Benachrichtigungen, dem Bildschirm „Letzte“ und dem Always-on-VPN.
Alle Änderungen für Unternehmen in Android 8.0 (API-Ebene 26) und ihre Auswirkungen auf Ihre App finden Sie unter Android in Unternehmen.
Apps für Android 8.0
Diese Verhaltensänderungen gelten ausschließlich für Apps, die auf Android 8.0 (API-Level 26) oder höher ausgerichtet sind. Entwickler von Apps, die für Android 8.0 kompiliert werden oder für die targetSdkVersion
auf Android 8.0 oder höher festgelegt ist, müssen ihre Apps entsprechend anpassen, sofern dies für die App zutrifft.
Benachrichtigungsfenster
Apps, die die Berechtigung SYSTEM_ALERT_WINDOW
verwenden, können die folgenden Fenstertypen nicht mehr verwenden, um Benachrichtigungsfenster über anderen Apps und Systemfenstern anzuzeigen:
Stattdessen müssen Apps einen neuen Fenstertyp namens TYPE_APPLICATION_OVERLAY
verwenden.
Wenn Sie den Fenstertyp TYPE_APPLICATION_OVERLAY
verwenden, um Benachrichtigungsfenster für Ihre App anzuzeigen, beachten Sie die folgenden Eigenschaften des neuen Fenstertyps:
- Die Benachrichtigungsfenster einer App werden immer unter wichtigen Systemfenstern wie der Statusleiste und der Eingabemethode angezeigt.
- Das System kann Fenster, die den Fenstertyp
TYPE_APPLICATION_OVERLAY
verwenden, verschieben oder deren Größe anpassen, um die Bildschirmdarstellung zu verbessern. - Wenn Nutzer die Benachrichtigungsleiste öffnen, können sie die Einstellungen aufrufen, um zu verhindern, dass eine App Warnfenster mit dem Fenstertyp
TYPE_APPLICATION_OVERLAY
anzeigt.
Benachrichtigungen zu Inhaltsänderungen
Mit Android 8.0 (API-Level 26) ändert sich das Verhalten von ContentResolver.notifyChange()
und registerContentObserver(Uri, boolean, ContentObserver)
für Apps, die auf Android 8.0 ausgerichtet sind.
Für diese APIs muss jetzt in allen URIs ein gültiger ContentProvider
für die Zertifizierungsstelle definiert sein. Wenn Sie eine gültige ContentProvider
mit den entsprechenden Berechtigungen definieren, können Sie Ihre App besser vor Inhaltsänderungen durch schädliche Apps schützen und verhindern, dass potenziell vertrauliche Daten an schädliche Apps weitergegeben werden.
Fokus ansehen
Klickbare View
-Objekte sind jetzt standardmäßig fokussierbar. Wenn ein View
-Objekt anklickbar, aber nicht fokussierbar sein soll, legen Sie das
android:focusable
-Attribut in der Layout-XML-Datei, die View
enthält, auf false
fest oder übergeben Sie false
in der UI-Logik Ihrer App an setFocusable()
.
User-Agent-Abgleich bei der Browsererkennung
Android 8.0 (API-Level 26) und höher enthalten den Build-ID-String OPR
. Einige Musterübereinstimmungen können dazu führen, dass die Browsererkennung einen anderen Browser als Opera identifiziert.
Hier ist ein Beispiel für eine solche Musterübereinstimmung:
if(p.match(/OPR/)){k="Opera";c=p.match(/OPR\/(\d+.\d+)/);n=new Ext.Version(c[1])}
Um Probleme aufgrund einer solchen Fehlidentifikation zu vermeiden, verwenden Sie einen anderen String als OPR
als Musterabgleich für den Opera-Browser.
Sicherheit
Die folgenden Änderungen wirken sich auf die Sicherheit in Android 8.0 (API-Level 26) aus:
- Wenn die Netzwerksicherheitskonfiguration Ihrer Anwendung die Unterstützung von Klartext-Traffic deaktiviert, können die
WebView
-Objekte Ihrer App nicht über HTTP auf Websites zugreifen. Stattdessen muss für jedesWebView
-Objekt HTTPS verwendet werden. - Die Systemeinstellung Unbekannte Quellen zulassen wurde entfernt. Stattdessen wird die Installation unbekannter Apps aus unbekannten Quellen jetzt über die Berechtigung Unbekannte Apps installieren verwaltet. Weitere Informationen zu dieser neuen Berechtigung finden Sie im Leitfaden Berechtigungen zum Installieren unbekannter Apps.
Weitere Richtlinien zur Erhöhung der Sicherheit deiner App findest du unter Sicherheit für Android-Entwickler.
Kontozugriff und Sichtbarkeit
In Android 8.0 (API-Level 26) können Apps nur dann auf Nutzerkonten zugreifen, wenn der Authenticator der Inhaber der Konten ist oder der Nutzer den Zugriff gewährt. Die Berechtigung GET_ACCOUNTS
reicht nicht mehr aus. Damit Apps Zugriff auf ein Konto erhalten, müssen sie entweder AccountManager.newChooseAccountIntent()
oder eine Authenticator-spezifische Methode verwenden. Nachdem eine App Zugriff auf Konten erhalten hat, kann sie AccountManager.getAccounts()
aufrufen, um darauf zuzugreifen.
Unter Android 8.0 wird LOGIN_ACCOUNTS_CHANGED_ACTION
eingestellt. Apps sollten stattdessen addOnAccountsUpdatedListener()
verwenden, um während der Laufzeit Aktualisierungen zu Konten zu erhalten.
Informationen zu den neuen APIs und Methoden für den Kontozugriff und die Sichtbarkeit finden Sie im Abschnitt Neue APIs unter Kontozugriff und Sichtbarkeit.
Datenschutz
Die folgenden Änderungen wirken sich auf den Datenschutz in Android 8.0 (API-Ebene 26) aus.
-
Die Systemeigenschaften
net.dns1
,net.dns2
,net.dns3
undnet.dns4
sind nicht mehr verfügbar. Durch diese Änderung wird der Datenschutz auf der Plattform verbessert. -
Um Netzwerkinformationen wie DNS-Server abzurufen, können Apps mit der Berechtigung
ACCESS_NETWORK_STATE
einNetworkRequest
- oderNetworkCallback
-Objekt registrieren. Diese Klassen sind ab Android 5.0 (API-Level 21) verfügbar. -
Build.SERIAL wurde eingestellt.
Apps, die die Hardware-Seriennummer benötigen, sollten stattdessen die neue Methode
Build.getSerial()
verwenden, für die die BerechtigungREAD_PHONE_STATE
erforderlich ist. -
Über die
LauncherApps
API können Apps in Arbeitsprofilen keine Informationen mehr über das Hauptprofil abrufen. Wenn sich ein Nutzer in einem Arbeitsprofil befindet, verhält sich dieLauncherApps
API so, als wären keine Anwendungen in anderen Profilen innerhalb derselben Profilgruppe installiert. Wie bisher führen Versuche, auf nicht zueinander gehörende Profile zuzugreifen, zu SecurityExceptions.
Berechtigungen
Vor Android 8.0 (API-Ebene 26) wurde einer App, die zur Laufzeit eine Berechtigung anforderte und die Berechtigung auch erhielt, fälschlicherweise auch der Rest der Berechtigungen erteilt, die zu derselben Berechtigungsgruppe gehörten und im Manifest registriert waren.
Bei Apps, die auf Android 8.0 ausgerichtet sind, wurde dieses Verhalten korrigiert. Der App werden nur die Berechtigungen gewährt, die sie ausdrücklich angefordert hat. Sobald der Nutzer der App jedoch eine Berechtigung erteilt hat, werden alle nachfolgenden Berechtigungsanfragen in dieser Berechtigungsgruppe automatisch gewährt.
Beispiel: Eine App listet in ihrem Manifest sowohl READ_EXTERNAL_STORAGE
als auch WRITE_EXTERNAL_STORAGE
auf.
Die App fordert READ_EXTERNAL_STORAGE
an und der Nutzer gewährt sie. Wenn die App auf API-Level 25 oder niedriger ausgerichtet ist, gewährt das System gleichzeitig auch WRITE_EXTERNAL_STORAGE
, da die App zur selben STORAGE
-Berechtigungsgruppe gehört und auch im Manifest registriert ist. Wenn die App auf Android 8.0 (API-Level 26) ausgerichtet ist, gewährt das System zu diesem Zeitpunkt nur READ_EXTERNAL_STORAGE
. Wenn die App jedoch später WRITE_EXTERNAL_STORAGE
anfordert, gewährt das System diese Berechtigung sofort, ohne dass der Nutzer dazu aufgefordert wird.
Medien
- Das Framework kann automatische Audio-Ducking-Funktionen selbst ausführen. Wenn in diesem Fall eine andere Anwendung den Fokus mit
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
anfordert, reduziert die App, die den Fokus hat, ihre Lautstärke, erhält aber in der Regel keinenonAudioFocusChange()
-Callback und verliert den Audiofokus nicht. Es gibt neue APIs, mit denen dieses Verhalten für Anwendungen überschrieben werden kann, die angehalten werden müssen, anstatt leiser gestellt zu werden. - Wenn der Nutzer einen Anruf annimmt, werden aktive Medienstreams für die Dauer des Anrufs stummgeschaltet.
- In allen audiobezogenen APIs sollte
AudioAttributes
anstelle von Audiostreamtypen verwendet werden, um den Anwendungsfall der Audiowiedergabe zu beschreiben. Audiostreamtypen sollten nur noch für die Lautstärkeregelung verwendet werden. Andere Verwendungen von Streamtypen funktionieren weiterhin (z. B. dasstreamType
-Argument für den veralteten KonstruktorAudioTrack
), werden aber vom System als Fehler protokolliert. - Wenn die Anwendung bei Verwendung eines
AudioTrack
einen ausreichend großen Audiopuffer anfordert, versucht das Framework, die Tiefenpufferausgabe zu verwenden, sofern diese verfügbar ist. - Unter Android 8.0 (API-Ebene 26) werden Ereignisse von Medienschaltflächen anders verarbeitet:
- Die Verarbeitung von Medienschaltflächen in einer UI-Aktivität hat sich nicht geändert: Aktivitäten im Vordergrund haben weiterhin Vorrang bei der Verarbeitung von Ereignissen von Medienschaltflächen.
- Wenn die Aktivität im Vordergrund das Ereignis der Medientaste nicht verarbeitet, leitet das System das Ereignis an die App weiter, die zuletzt lokal Audio abgespielt hat. Der aktive Status, Flags und der Wiedergabestatus einer Mediensitzung werden nicht berücksichtigt, wenn ermittelt wird, welche App Medienschalter-Ereignisse empfängt.
- Wenn die Mediensitzung der App freigegeben wurde, sendet das System das Medienschalter-Ereignis an die
MediaButtonReceiver
der App, falls vorhanden. - In allen anderen Fällen verwirft das System das Ereignis der Medientaste.
Native Bibliotheken
In Apps, die auf Android 8.0 (API-Ebene 26) ausgerichtet sind, werden native Bibliotheken nicht mehr geladen, wenn sie ein Ladesegment enthalten, das sowohl beschreibbar als auch ausführbar ist. Einige Apps funktionieren aufgrund dieser Änderung möglicherweise nicht mehr, wenn sie native Bibliotheken mit falschen Ladesegmenten haben. Dies ist eine Maßnahme zur Erhöhung der Sicherheit.
Weitere Informationen finden Sie unter Beschreibbare und ausführbare Segmente.
Linkeränderungen sind an die API-Ebene gebunden, auf die eine App ausgerichtet ist. Wenn sich der Linker auf der Ziel-API-Ebene ändert, kann die App die Bibliothek nicht laden. Wenn Sie eine API-Ebene ansteuern, die niedriger ist als die API-Ebene, auf der die Linkeränderung auftritt, wird in logcat eine Warnung angezeigt.
Umgang mit Datenerhebung
Unter Android 8.0 (API-Ebene 26) wird Collections.sort()
über List.sort()
implementiert. In Android 7.x (API-Ebenen 24 und 25) war das Gegenteil der Fall: Die Standardimplementierung von List.sort()
hieß Collections.sort()
.
Durch diese Änderung kann Collections.sort()
von optimierten List.sort()
-Implementierungen profitieren. Es gelten jedoch die folgenden Einschränkungen:
Implementierungen von
List.sort()
dürfenCollections.sort()
nicht aufrufen, da dies zu einem Stacküberlauf aufgrund unendlicher Rekursion führen würde. Wenn Sie stattdessen das Standardverhalten in IhrerList
-Implementierung verwenden möchten, sollten Siesort()
nicht überschreiben.Wenn eine übergeordnete Klasse
sort()
nicht ordnungsgemäß implementiert, ist es in der Regel in Ordnung,List.sort()
mit einer Implementierung zu überschreiben, die aufList.toArray()
,Arrays.sort()
undListIterator.set()
basiert. Beispiel:@Override public void sort(Comparator<? super E> c) { Object[] elements = toArray(); Arrays.sort(elements, c); ListIterator<E> iterator = (ListIterator<Object>) listIterator(); for (Object element : elements) { iterator.next(); iterator.set((E) element); } }
In den meisten Fällen können Sie
List.sort()
auch mit einer Implementierung überschreiben, die je nach API-Ebene an verschiedene Standardimplementierungen delegiert. Beispiel:@Override public void sort(Comparator<? super E> comparator) { if (Build.VERSION.SDK_INT <= 25) { Collections.sort(this); } else { super.sort(comparator); } }
Wenn Sie das nur tun, weil Sie eine
sort()
-Methode auf allen API-Ebenen verfügbar haben möchten, sollten Sie ihr einen eindeutigen Namen wiesortCompat()
geben, anstattsort()
zu überschreiben.-
Collections.sort()
gilt jetzt als strukturelle Änderung in Listenimplementierungen, diesort()
aufrufen. In Versionen der Plattform vor Android 8.0 (API-Level 26) würde beispielsweise bei der Iteration über eineArrayList
und dem Aufruf vonsort()
in der Mitte der Iteration eineConcurrentModificationException
geworfen werden, wenn die Sortierung durch Aufrufen vonList.sort()
erfolgt.Collections.sort()
hat keine Ausnahme ausgelöst.Durch diese Änderung wird das Plattformverhalten einheitlicher: Beide Ansätze führen jetzt zu einem
ConcurrentModificationException
.
Verhalten beim Laden von Klassen
Unter Android 8.0 (API-Ebene 26) wird geprüft, ob die Klassenlader beim Laden neuer Klassen die Annahmen der Laufzeit nicht verletzen. Diese Prüfungen werden durchgeführt, unabhängig davon, ob auf die Klasse aus Java (forName()
), aus Dalvik-Bytecode oder aus JNI verwiesen wird. Die Plattform fängt keine direkten Aufrufe von Java an die Methode loadClass()
ab und prüft auch nicht die Ergebnisse solcher Aufrufe. Dieses Verhalten sollte sich nicht auf die Funktionsweise ordnungsgemäßer Class Loader auswirken.
Die Plattform prüft, ob der Descriptor der Klasse, den der Klassenloader zurückgibt, mit dem erwarteten Descriptor übereinstimmt. Wenn der zurückgegebene Descriptor nicht übereinstimmt, löst die Plattform einen NoClassDefFoundError
-Fehler aus und speichert in der Ausnahme eine detaillierte Meldung, in der die Abweichung angegeben wird.
Außerdem wird geprüft, ob die Beschreibungen der angeforderten Klassen gültig sind. Diese Prüfung fängt JNI-Aufrufe ab, die Klassen wie GetFieldID()
indirekt laden und diesen Klassen ungültige Descriptor übergeben. Ein Feld mit der Signatur java/lang/String
wird beispielsweise nicht gefunden, weil diese Signatur ungültig ist. Sie muss Ljava/lang/String;
sein.
Dies unterscheidet sich von einem JNI-Aufruf von FindClass()
, wobei java/lang/String
ein gültiger vollständig qualifizierter Name ist.
Android 8.0 (API-Level 26) unterstützt nicht, dass mehrere Klassenlader versuchen, Klassen mit demselben DexFile-Objekt zu definieren. Bei einem solchen Versuch löst die Android-Laufzeit einen InternalError
-Fehler mit der Meldung „Attempt to register dex file <filename>
with multiple class loaders“ (Versuch, die Dex-Datei <filename>
mit mehreren Klassenladern zu registrieren) aus.
Die DexFile API ist jetzt eingestellt. Wir empfehlen Ihnen dringend, stattdessen einen der Plattform-Klassenloader wie PathClassLoader
oder BaseDexClassLoader
zu verwenden.
Hinweis : Sie können mehrere Klassenlader erstellen, die auf denselben APK- oder JAR-Dateicontainer aus dem Dateisystem verweisen. Das führt normalerweise nicht zu einem großen Speicheraufwand: Wenn DEX-Dateien im Container gespeichert statt komprimiert werden, kann die Plattform einen mmap
-Vorgang auf ihnen ausführen, anstatt sie direkt zu extrahieren. Wenn die Plattform jedoch die DEX-Datei aus dem Container extrahieren muss, kann das Verweisen auf eine DEX-Datei auf diese Weise viel Arbeitsspeicher belegen.
Unter Android gelten alle Klassenlader als parallelfähig. Wenn mehrere Threads versuchen, dieselbe Klasse mit demselben Classloader zu laden, gewinnt der erste Thread, der den Vorgang abschließt, und das Ergebnis wird für die anderen Threads verwendet. Dieses Verhalten tritt unabhängig davon auf, ob das Klassenladeprogramm dieselbe Klasse, eine andere Klasse oder eine Ausnahme zurückgegeben hat. Solche Ausnahmen werden von der Plattform ignoriert.
Achtung : Bei Versionen der Plattform, die niedriger als Android 8.0 (API-Level 26) sind, kann das Brechen dieser Annahmen dazu führen, dass dieselbe Klasse mehrmals definiert wird, dass der Heap aufgrund von Klassenverwirrung beschädigt wird und dass es zu anderen unerwünschten Auswirkungen kommt.