Das Beste aus dem APK-Analyzer machen

Wojtek Kaliciński

Follow

Nov 23, 2016 – 6 min read

Eine meiner liebsten Neuerungen in Android Studio ist der APK Analyzer, den man im oberen Menü unter Build → Analyze APK finden kann.

Pro-Tipp: Sie können APK-Dateien auch per Drag & Drop in den Editor ziehen, um sie zu öffnen

Mit dem APK Analyzer können Sie den Inhalt jeder APK-Datei öffnen und untersuchen, die Sie auf Ihrem Computer haben, entweder aus Ihrem lokalen Android Studio-Projekt erstellt oder von Ihrem Build-Server oder einem anderen Artefakt-Repository erworben. Es muss nicht aus einem Projekt erstellt werden, das Sie in Android Studio geöffnet haben, und Sie benötigen nicht den Quellcode für diese bestimmte APK.

Hinweis: APK Analyzer funktioniert am besten mit Release-Builds. Wenn Sie einen Debug-Build Ihrer App analysieren müssen, stellen Sie sicher, dass Sie eine APK verwenden, die nicht für Instant Run instrumentiert ist. Um diese zu erhalten, können Sie den Befehl Build → Build APK verwenden. Sie können feststellen, ob Sie eine für Instant Run instrumentierte APK geöffnet haben, indem Sie das Vorhandensein einer instant-run.zip-Datei im Archiv überprüfen.

Der APK-Analysator ist eine großartige Möglichkeit, in APK-Dateien herumzustochern und etwas über ihre Struktur zu erfahren, den Inhalt der Datei vor der Freigabe zu überprüfen oder einige häufige Probleme zu beheben, einschließlich APK-Größen- und DEX-Probleme.

Der APK-Analysator kann Ihnen viele nützliche, umsetzbare Informationen über die App-Größe liefern. Am oberen Rand des Bildschirms sehen Sie die Rohdateigröße, die nur die APK-Größe auf der Festplatte ist. Die Download-Größe zeigt eine Schätzung der Datenmenge an, die für den Download Ihrer App benötigt wird, wobei die vom Play Store angewandte Komprimierung berücksichtigt wird.

Die Liste der Dateien und Ordner ist nach Gesamtgröße in absteigender Reihenfolge sortiert. Das macht sie ideal, um die niedrig hängenden Früchte der APK-Größenoptimierung zu identifizieren. Jedes Mal, wenn Sie einen Ordner aufschlüsseln, können Sie die Ressourcen und andere Entitäten sehen, die den meisten Platz in Ihrer APK einnehmen.

Ressourcen in absteigender Reihenfolge nach Größe sortiert

In diesem Beispiel konnte ich bei der Untersuchung einer APK auf mögliche Größenreduzierungen sofort feststellen, dass eine 3-Frame-PNG-Animation mit einem Gewicht von 1,5 MB der größte Teil der zeichenbaren Ressourcen ist.

Da diese Bilder wie perfekte Kandidaten für die Speicherung als Vektoren aussehen, haben wir die Quelldateien für das Artwork gefunden und sie als VectorDrawables importiert, indem wir die neue PSD-Unterstützung im Vector Asset-Import-Tool in Android Studio 2.2 verwendet haben.

Indem wir den gleichen Prozess für die andere verbleibende Animation (instruction_touch_*.png) durchgeführt und diese PNG-Dateien in allen Dichten entfernt haben, konnten wir über 5 MB einsparen. Um die Abwärtskompatibilität aufrechtzuerhalten, haben wir VectorDrawableCompat aus der Support-Bibliothek verwendet.

Beim Blick auf andere Ressourcenordner war es einfach, einige unkomprimierte WAV-Dateien zu entdecken, die in OGG konvertiert werden konnten, was noch mehr Einsparungen bedeutete, ohne eine Zeile Code zu berühren.

Durchsuchen anderer Ordner im APK

Als nächstes stand der Ordner lib/ auf der Liste der zu überprüfenden Dinge, der native Bibliotheken für die drei von uns unterstützten ABIs enthält.

Die Entscheidung wurde getroffen, die APK-Split-Unterstützung in unserem Gradle-Build zu verwenden, um separate Versionen der App für jede ABI zu erstellen.

Ich sah mir als Nächstes die AndroidManifest.xml an und bemerkte, dass <application> das Attribut android:extractNativeLibs fehlt. Wenn man dieses Attribut auf false setzt, kann man etwas Platz auf dem Gerät sparen, da es das Kopieren der nativen Bibliotheken aus der APK in das Dateisystem verhindert. Die einzige Voraussetzung ist, dass die Dateien seitenorientiert und unkomprimiert in der APK gespeichert sind, was mit dem neuen Packager im Android Gradle Plugin ab Version 2.2.0 unterstützt wird.

Die vollständige AndroidManifest.xml, wie sie in APK Analyzer angezeigt wird

Nachdem ich diese Änderungen vorgenommen hatte, war ich neugierig zu sehen, wie die neue Version der App im Vergleich zu der vorherigen ist. Dazu habe ich den Quellcode aus dem Git-Commit, mit dem ich begonnen hatte, ausgecheckt, die APK kompiliert und in einem anderen Ordner gespeichert. Dann habe ich die Funktion Vergleichen mit… verwendet, um eine Aufschlüsselung der Größenunterschiede zwischen den alten und neuen Builds zu sehen.

APK-Vergleich – Zugriff über die Schaltfläche oben rechts

Wir haben bei den Ressourcen und nativen Bibliotheken große Fortschritte gemacht und insgesamt 17 MB eingespart, wobei die App nur wenig verändert wurde. Ich kann jedoch feststellen, dass die DEX-Größe zurückgegangen ist, wobei die Datei classes2.dex um 400 KB gewachsen ist.

Debugging von DEX-Problemen

In diesem Fall kam der Unterschied durch die Aktualisierung unserer Abhängigkeiten auf neuere Versionen und das Hinzufügen neuer Bibliotheken. Proguard und Multidex waren bereits für unsere Builds aktiviert, so dass wir nicht viel an der DEX-Größe ändern konnten. Dennoch ist APK Analyzer ein großartiges Werkzeug, um Probleme mit diesem Setup zu debuggen, besonders wenn man Multidex oder Proguard zum ersten Mal für sein Projekt aktiviert.

Untersuchung des Inhalts von Klassen.dex

Wenn Sie auf eine beliebige DEX-Datei klicken, sehen Sie eine Zusammenfassung, wie viele Klassen und Methoden sie definiert und wie viele Referenzen sie insgesamt enthält (es sind die Referenzen, die auf die 64K-Grenze in einer einzelnen DEX-Datei angerechnet werden). In diesem Beispiels-Screenshot ist die Anwendung kurz davor, das Limit zu erreichen, was bedeutet, dass MultiDex die Klassen in naher Zukunft in separate Dateien aufteilen muss.

Sie können die Pakete aufschlüsseln, um zu sehen, welche Pakete alle Referenzen verbrauchen. In diesem Fall können wir sehen, dass die Support-Bibliothek und die Google Play Services die Hauptursachen für diese Situation sind:

Referenzzahlen pro Paket

Wenn Sie MultiDex aktiviert und Ihre App kompiliert haben, werden Sie eine zweite classes2.dex Datei (und möglicherweise classes3.dex, und so weiter). Die MultiDex-Lösung im Android-Gradle-Plugin findet heraus, welche Klassen benötigt werden, um Ihre App zu starten, und fügt sie in die primäre Datei classes.dex ein. In dem seltenen Fall, dass dies nicht funktioniert und Sie eine ClassNotFoundException erhalten, können Sie den APK Analyzer verwenden, um die DEX-Dateien zu untersuchen und dann zu erzwingen, dass die fehlenden Klassen in die primäre DEX-Datei eingefügt werden.

Sie werden auf ähnliche Probleme stoßen, wenn Sie Proguard aktivieren und Klassen oder Methoden durch Reflection oder aus XML-Layouts verwenden. Mit dem APK Analyzer können Sie überprüfen, ob Ihre Proguard-Konfiguration korrekt ist, indem Sie einfach überprüfen, ob die von Ihnen benötigten Methoden und Klassen in der APK vorhanden sind und ob sie umbenannt (verschleiert) werden. Sie können auch sicherstellen, dass die Klassen, die Sie entfernen möchten, tatsächlich entfernt werden und nicht Ihre kostbare Anzahl an Referenzmethoden belegen.

Wir sind neugierig zu erfahren, welche anderen Verwendungsmöglichkeiten Sie für den APK Analyzer finden und welche anderen Funktionen Sie gerne in das Tool integriert sehen würden!

Schreibe einen Kommentar