Wenn Sie Ihre App bei Google Play veröffentlichen, sollten Sie ein Android App Bundle erstellen und hochladen. In diesem Fall erstellt Google Play automatisch optimierte APKs und stellt sie für die Gerätekonfiguration der einzelnen Nutzer bereit. Dadurch werden nur der Code und die Ressourcen heruntergeladen, die für die Ausführung deiner App erforderlich sind. Die Veröffentlichung mehrerer APKs ist sinnvoll, wenn du nicht bei Google Play veröffentlichst, aber du jedes APK selbst erstellen, signieren und verwalten musst.
Wenn Sie Ihre Android-Anwendung so entwickeln, dass Sie mehrere APKs bei Google Play nutzen können, ist es wichtig, von Anfang an einige Best Practices zu beachten, um spätere Probleme zu vermeiden. In dieser Lektion erfährst du, wie du mehrere APKs deiner App erstellst, die jeweils eine andere Teilmenge von OpenGL-Texturformaten unterstützen. Außerdem lernen Sie einige Tools kennen, mit denen sich die Pflege einer Codebasis mit mehreren APKs so einfach wie möglich gestalten lässt.
Prüfen, ob mehrere APKs erforderlich sind
Wenn Sie eine Anwendung erstellen, die auf allen verfügbaren Android-Geräten funktioniert, möchten Sie natürlich, dass sie auf jedem einzelnen Gerät optimal aussieht, unabhängig davon, dass nicht alle Geräte dieselben GL-Texturen unterstützen. Auf den ersten Blick mag es so aussehen, als wäre die Unterstützung mehrerer APKs die beste Lösung, aber das ist oft nicht der Fall. Der Abschnitt Using Single APK Stattad (Statt ein einzelnes APK verwenden) des Entwicklerhandbuchs für mehrere APKs enthält einige nützliche Informationen dazu, wie du dies mit einem einzelnen APK bewerkstelligen kannst. Außerdem erfährst du, wie du unterstützte Texturformate zur Laufzeit erkennst. Je nach Situation kann es einfacher sein, alle Formate mit Ihrer Anwendung zu bündeln und bei der Laufzeit einfach auszuwählen, welches verwendet werden soll.
Wenn Sie Ihre Anwendung auf ein einzelnes APK beschränken können, hat das mehrere Vorteile, darunter:
- Einfachere Veröffentlichung und Tests
- Es muss nur eine Codebasis verwaltet werden
- Deine App kann sich an Änderungen der Gerätekonfiguration anpassen
- Geräteübergreifende App-Wiederherstellung funktioniert einfach
- Sie müssen sich keine Gedanken über Marktpräferenzen, das Verhalten von „Upgrades“ von einem APK auf das nächste oder darüber machen, welches APK zu welcher Geräteklasse gehört.
Im Rest dieser Lektion wird davon ausgegangen, dass Sie sich mit dem Thema befasst, sich das Material in den verlinkten Ressourcen sorgfältig angesehen und festgestellt haben, dass mehrere APKs der richtige Weg für Ihre Anwendung sind.
Anforderungen skizzieren
Im Android-Entwicklerhandbuch findest du eine praktische Referenz für einige gängige unterstützte Texturen auf der Seite "supports-gl-texture". Auf dieser Seite finden Sie auch einige Hinweise dazu, welche Smartphones (oder Smartphone-Modelle) bestimmte Texturformate unterstützen. Im Allgemeinen empfiehlt es sich, eines deiner APKs ETC1 zu unterstützen, da dieses Texturformat von allen Android-Geräten unterstützt wird, die die OpenGL ES 2.0-Spezifikation unterstützen.
Da die meisten Android-Geräte mehrere Texturformate unterstützen, müssen Sie eine bevorzugte Reihenfolge festlegen. Erstellen Sie ein Diagramm mit allen Formaten, die Ihre Anwendung unterstützen wird. Die Zelle ganz links hat die niedrigste Priorität. Es wird wahrscheinlich ETC1 sein, eine wirklich solide Standardeinstellung in Bezug auf Leistung und Kompatibilität. Färben Sie das Diagramm dann so ein, dass jede Zelle ein APK darstellt.
ETC1 | ATI | PowerVR |
Die Farbgebung des Diagramms macht diesen Leitfaden nicht nur weniger einfarbig, sondern erleichtert auch die Kommunikation innerhalb des Teams. Sie können jetzt einfach auf die einzelnen APKs als „blau“, „grün“ oder „rot“ verweisen, anstatt „Diejenige, die ETC1-Texturformate unterstützt“ usw.
Alle gängigen Codes und Ressourcen in einem Bibliotheksprojekt speichern
Ganz gleich, ob Sie eine vorhandene Android-Anwendung ändern oder eine neue erstellen, ist dies das Erste, was Sie mit der Codebasis tun sollten, und bei weitem das Wichtigste. Alles, was in das Bibliotheksprojekt aufgenommen wird, muss nur einmal aktualisiert werden (z. B. sprachlokalisierte Strings, Farbthemen, im gemeinsamen Code behobene Fehler). Das verkürzt die Entwicklungszeit und verringert die Wahrscheinlichkeit von Fehlern, die leicht hätten vermieden werden können.
Hinweis:Die Implementierungsdetails zum Erstellen und Einbinden von Bibliotheksprojekten werden in dieser Lektion nicht behandelt. Weitere Informationen erhalten Sie unter Android-Bibliothek erstellen.
Wenn Sie eine vorhandene Anwendung so konvertieren, dass sie mehrere APKs unterstützt, durchsuchen Sie Ihre Codebasis nach allen lokalisierten Stringdateien, Listen von Werten, Themenfarben, Menüsymbolen und Layouts, die sich nicht in den APKs ändern, und fügen Sie sie dem Bibliotheksprojekt hinzu. Code, der sich nicht wesentlich ändern wird, sollte ebenfalls in das Bibliotheksprojekt aufgenommen werden. Sie werden diese Klassen wahrscheinlich erweitern, um eine oder zwei Methoden von APK zu APK hinzuzufügen.
Wenn Sie die Anwendung hingegen von Grund auf neu erstellen, sollten Sie zuerst Code im Bibliotheksprojekt schreiben und ihn dann nur bei Bedarf in ein einzelnes APK verschieben. Das ist auf lange Sicht viel einfacher, als ihn erst einem, dann einem anderen und dann noch einem anderen hinzuzufügen und Monate später herauszufinden, ob dieser Blob in den Bibliotheksabschnitt verschoben werden kann, ohne etwas zu vermasseln.
Neue APK-Projekte erstellen
Für jedes APK, das Sie veröffentlichen möchten, sollte es ein separates Android-Projekt geben. Für eine einfache Organisation sollten Sie das Bibliotheksprojekt und alle zugehörigen APK-Projekte im selben übergeordneten Ordner ablegen. Denken Sie auch daran, dass jedes APK denselben Paketnamen haben muss, der aber nicht unbedingt mit dem der Bibliothek übereinstimmen muss. Wenn Sie drei APKs gemäß dem oben beschriebenen Schema haben, könnte Ihr Stammverzeichnis so aussehen:
alexlucas:~/code/multi-apks-root$ ls foo-blue foo-green foo-lib foo-red
Fügen Sie nach dem Erstellen der Projekte das Bibliotheksprojekt jedem APK-Projekt als Referenz hinzu. Definieren Sie nach Möglichkeit die Startaktivität im Bibliotheksprojekt und erweitern Sie diese Aktivität in Ihrem APK-Projekt. Wenn Sie im Bibliotheksprojekt eine Startaktivität definieren, können Sie die gesamte Anwendungsinitialisierung an einem Ort zusammenfassen. So müssen in jedem einzelnen APK nicht wieder „universelle“ Aufgaben wie die Initialisierung von Analytics, die Durchführung von Lizenzprüfungen und andere Initialisierungsverfahren implementiert werden, die sich von APK zu APK nicht wesentlich ändern.
Manifeste anpassen
Wenn ein Nutzer eine App über Google Play herunterlädt, die mehrere APKs verwendet, wird anhand einiger einfacher Regeln das richtige APK ausgewählt:
- Im Manifest muss angegeben sein, dass das betreffende APK berechtigt ist.
- Von den infrage kommenden APKs hat das APK mit der höchsten Versionsnummer Vorrang.
- Wenn eines der in deinem APK aufgeführten Texturformate von dem auf dem Markt erhältlichen Gerät unterstützt wird, gilt dieses Gerät als zulässig.
Bei GL-Texturen ist diese letzte Regel wichtig. Das bedeutet, dass Sie beispielsweise sehr vorsichtig sein sollten, wenn Sie unterschiedliche GL-Formate in derselben Anwendung verwenden. Wenn Sie 99% der Zeit PowerVR verwenden, aber beispielsweise ETC1 für Ihren Splashscreen… In diesem Fall muss Ihr Manifest die Unterstützung beider Formate angeben. Ein Gerät, das nur ETC1 unterstützt, gilt als kompatibel, deine App wird heruntergeladen und der Nutzer sieht einige spannende Absturzmeldungen. Wenn Sie mehrere APKs verwenden, die speziell auf verschiedene Geräte mit GL-Texturunterstützung ausgerichtet sind, wird in der Regel ein Texturformat pro APK verwendet.
Dadurch unterscheidet sich die Texturunterstützung ein wenig von den beiden anderen APK-Abmessungen, dem API-Level und der Bildschirmgröße. Jedes Gerät hat nur eine API-Ebene und eine Bildschirmgröße. Es liegt in der Verantwortung des APK, eine Reihe davon zu unterstützen. Bei Texturen unterstützt das APK in der Regel eine Textur und das Gerät viele. Es gibt oft Überschneidungen, wenn ein Gerät viele APKs unterstützt. Die Lösung ist jedoch dieselbe: Versionscodes.
Sehen wir uns zum Beispiel bei einigen Geräten an, wie viele der zuvor definierten APKs zu jedem Gerät passen.
FooPhone | Nexus S | Evo |
ETC1 | ETC1 | ETC1 |
PowerVR | ATI TC |
Angenommen, PowerVR- und ATI-Formate werden bei Verfügbarkeit ETC1 vorgezogen. Wenn wir das Attribut „versionCode“ in jedem APK so festlegen, dass „rot“ ≥ „grün“ ≥ „blau“ ist, wird gemäß der Regel „Höchste Versionsnummer gewinnt“ auf Geräten, die sie unterstützen, immer „rot“ und „grün“ anstelle von „blau“ ausgewählt. Sollte ein Gerät auf den Markt kommen, das sowohl „rot“ als auch „grün“ unterstützt, wird „rot“ ausgewählt.
Damit alle Ihre APKs in separaten „Tracks“ bleiben, ist ein gutes Versionscode-Schema wichtig. Die empfohlene Version findest du im Bereich „Versionscodes“ unseres Entwicklerhandbuchs. Da es sich bei den Beispiel-APKs nur um eine von drei möglichen Dimensionen handelt, reicht es aus, jedes APK um 1.000 zu trennen und von dort aus zu inkrementieren. Das könnte so aussehen:
Blau: 1001, 1002, 1003, 1004…
Grün: 2001, 2002, 2003, 2004…
Rot:3001, 3002, 3003, 3004…
Zusammengenommen sehen Ihre Android-Manifeste in etwa so aus:
Blau:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1001" android:versionName="1.0" package="com.example.foo">
<supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
...
Grün:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="2001" android:versionName="1.0" package="com.example.foo">
<supports-gl-texture android:name="GL_AMD_compressed_ATC_texture" />
...
Rot:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="3001" android:versionName="1.0" package="com.example.foo">
<supports-gl-texture android:name="GL_IMG_texture_compression_pvrtc" />
...
Checkliste vor der Veröffentlichung ansehen
Prüfen Sie vor dem Hochladen bei Google Play die folgenden Punkte. Denken Sie daran, dass diese Punkte speziell für mehrere APKs relevant sind und keine vollständige Checkliste für alle Apps darstellen, die auf Google Play hochgeladen werden.
- Alle APKs müssen denselben Paketnamen haben.
- Alle APKs müssen mit demselben Zertifikat signiert sein.
- Prüfen Sie Ihre Manifestfilter auf widersprüchliche Informationen. Ein APK, das nur Cupcake auf XLARGE-Displays unterstützt, wird von niemandem gesehen.
- Das Manifest jedes APKs muss für mindestens eine der unterstützten Bildschirm-, OpenGL-Textur- oder Plattformversionen eindeutig sein.
- Testen Sie jedes APK auf mindestens einem Gerät. Andernfalls haben Sie auf Ihrem Entwicklungscomputer einen der am besten anpassbaren Geräteemulatoren der Branche. Viel Spaß!
Es empfiehlt sich auch, das kompilierte APK vor der Markteinführung zu prüfen, um sicherzugehen, dass es keine Überraschungen gibt, die Ihre App bei Google Play verbergen könnten. Mit dem Tool „aapt“ ist das ganz einfach. Aapt (das Android Asset Packaging Tool) ist Teil des Build-Prozesses zum Erstellen und Packen von Android-Anwendungen und außerdem ein sehr praktisches Tool für die Prüfung.
>aapt dump badging package: name='com.example.hello' versionCode='1' versionName='1.0' sdkVersion:'11' uses-permission:'android.permission.SEND_SMS' application-label:'Hello' application-icon-120:'res/drawable-ldpi/icon.png' application-icon-160:'res/drawable-mdpi/icon.png' application-icon-240:'res/drawable-hdpi/icon.png' application: label='Hello' icon='res/drawable-mdpi/icon.png' launchable-activity: name='com.example.hello.HelloActivity' label='Hello' icon='' uses-feature:'android.hardware.telephony' uses-feature:'android.hardware.touchscreen' main supports-screens: 'xlarge' supports-any-density: 'true' locales: '--_--' densities: '120' '160' '240'
Prüfen Sie bei der Prüfung der aapt-Ausgabe, ob es keine in Konflikt stehenden Werte für „supports-screens“ und „compatible-screens“ gibt und ob keine unbeabsichtigten „uses-feature“-Werte vorhanden sind, die aufgrund von Berechtigungen hinzugefügt wurden, die Sie im Manifest festgelegt haben. Im Beispiel oben ist das APK für die meisten, wenn nicht für alle Geräte unsichtbar.
Was steckt dahinter? Durch das Hinzufügen der erforderlichen Berechtigung „SEND_SMS“ wurde die Funktionsanforderung „android.hardware.telephony“ implizit hinzugefügt. Da es sich bei den meisten (wenn nicht sogar allen) großen Geräten um Tablets handelt, die keine Telefoniehardware enthalten, filtert Google Play dieses APK in diesen Fällen heraus, bis zukünftige Geräte verfügbar sind, die beide groß genug sind, um eine Meldung über eine große Bildschirmgröße zu erstellen und über Telefoniehardware zu verfügen.
Glücklicherweise lässt sich das Problem ganz einfach beheben, indem Sie Ihrem Manifest Folgendes hinzufügen:
<uses-feature android:name="android.hardware.telephony" android:required="false" />
Die Anforderung für android.hardware.touchscreen
wird ebenfalls implizit hinzugefügt. Wenn Ihr APK auf Fernsehern ohne Touchscreen angezeigt werden soll, fügen Sie Ihrem Manifest Folgendes hinzu:
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
Nachdem Sie die Schritte der Checkliste vor der Veröffentlichung abgeschlossen haben, laden Sie Ihre APKs bei Google Play hoch. Es kann etwas dauern, bis die App bei der Suche in Google Play angezeigt wird. Wenn das der Fall ist, führen Sie noch eine letzte Prüfung durch. Laden Sie die App auf alle Testgeräte herunter, die Sie möglicherweise haben, um sicherzustellen, dass die APKs auf die gewünschten Geräte ausgerichtet sind. Herzlichen Glückwunsch, Sie haben alles erledigt.