Het beste halen uit de APK analyzer

Wojtek Kaliciński

Follow

23 nov, 2016 – 6 min read

Eén van mijn favoriete recente toevoegingen aan Android Studio is de APK Analyzer, die je kunt vinden in het menu bovenaan onder Build → Analyze APK.

Pro-tip: u kunt ook APK-bestanden naar de editor slepen om ze te openen

APK Analyzer laat u de inhoud van elk APK-bestand dat u op uw computer hebt, openen en inspecteren, hetzij gebouwd vanuit uw lokale Android Studio-project of verkregen van uw build-server of andere artefactrepository. Het hoeft niet te zijn gebouwd vanuit een project dat u hebt geopend in Android Studio en u hebt de broncode voor die specifieke APK niet nodig.

Note: APK Analyzer werkt het beste met release builds. Als u een debug build van uw app moet analyseren, zorg er dan voor dat u een APK gebruikt die niet is geïnstrumenteerd voor Instant Run. Om deze te verkrijgen, kunt u het Build → Build APKcommando gebruiken. U kunt zien of u een geïnstrumenteerde Instant Run-APK hebt geopend door de aanwezigheid van een instant-run.zip-bestand in het archief te controleren.

Het gebruik van de APK-analysator is een geweldige manier om in APK-bestanden rond te neuzen en meer te weten te komen over hun structuur, de inhoud van het bestand te controleren voordat u het vrijgeeft of een aantal veelvoorkomende problemen te debuggen, waaronder problemen met de APK-grootte en DEX.

De APK-analysator kan u veel nuttige, bruikbare informatie geven over de app-grootte. Bovenaan het scherm zie je de Raw File Size, wat gewoon de APK on-disk grootte is. De Download grootte toont een schatting van hoeveel data wordt gebruikt om uw app te downloaden door rekening te houden met compressie toegepast door de Play Store.

De lijst van bestanden en mappen is gesorteerd op totale grootte in aflopende volgorde. Dit maakt het geweldig voor het identificeren van de laaghangend fruit van APK grootte optimalisatie. Telkens wanneer u een map opent, kunt u de bronnen en andere entiteiten zien die de meeste ruimte innemen in uw APK.

Bronnen gesorteerd in aflopende volgorde op grootte

In dit voorbeeld, toen ik een APK onderzocht op mogelijke verkleining, zag ik direct dat een 3-frame PNG-animatie het grootste deel uitmaakt van onze tekenbare bronnen, met een gewicht van 1.5MB, en dat is alleen voor de xxhdpi dichtheid!

Omdat deze beelden eruit zien als perfecte kandidaten voor het opslaan als vectoren, vonden we de bronbestanden voor het kunstwerk en importeerden ze als VectorDrawables met behulp van de nieuwe PSD-ondersteuning in de Vector Asset import toolin Android Studio 2.2.

Door het doorlopen van hetzelfde proces voor de andere resterende animatie (instructie_touch_*.png) en het verwijderen van deze PNG-bestanden over alle dichtheden, waren we in staat om meer dan 5MB te besparen. Om achterwaartse compatibiliteit te behouden, gebruikten we VectorDrawableCompat uit de ondersteuningsbibliotheek.

Een blik op andere bronmappen leverde al snel een aantal ongecomprimeerde WAV-bestanden op die konden worden geconverteerd naar OGG, wat nog meer besparing opleverde zonder ook maar een regel code aan te raken.

Doorzoeken van andere mappen in de APK

De volgende op de lijst van dingen om te controleren was de map lib/, die native bibliotheken bevat voor de drie ABI’s die we ondersteunen.

De beslissing werd genomen om de ondersteuning voor APK-splitsingen in onze Gradle te gebruiken om afzonderlijke versies van de app voor elke ABI te maken.

Ik keek vervolgens snel naar de AndroidManifest.xml en merkte op dat <application> het android:extractNativeLibs attribuut mist. Door dit attribuut op false te zetten kan wat ruimte op het toestel worden bespaard omdat het voorkomt dat de native libraries uit de APK naar het bestandssysteem worden gekopieerd. De enige vereiste is dat de bestanden pagina-opgelijnd zijn en ongecomprimeerd in de APK worden opgeslagen, wat wordt ondersteund met de nieuwe packager in de Android Gradle-plugin versie 2.2.0+.

De volledige AndroidManifest.xml zoals bekeken in APK Analyzer

Nadat ik deze wijzigingen had aangebracht, was ik nieuwsgierig om te zien hoe de nieuwe versie van de app zich verhoudt tot de vorige. Om dat te doen, checkte ik de broncode van de git commit waarmee ik begon, compileerde de APK en sloeg hem op in een andere map. Ik gebruikte toen de Compare with… functie om een uitsplitsing te zien van de grootte verschillen tussen de oude en nieuwe builds.

APK vergelijking – toegang via de knop rechtsboven

We hebben veel vooruitgang geboekt met de resources en native libraries, een totale besparing van 17MB met zeer weinig veranderingen in de app. Ik kan echter zien dat onze DEX-grootte is teruggelopen, waarbij de classes2.dex met 400KB is gegroeid.

Debugging DEX issues

In dit geval kwam het verschil van het upgraden van onze afhankelijkheden naar nieuwere versies en het toevoegen van nieuwe bibliotheken. Proguard en Multidex waren al ingeschakeld voor onze builds, dus er is niet veel dat kan worden gedaan over onze DEX grootte. Toch is APK analyzer een geweldig hulpmiddel om eventuele problemen met deze setup op te lossen, vooral wanneer u Multidex of Proguard voor het eerst inschakelt voor uw project.

Ontdekken van de inhoud van klassen.dex

Wanneer u op een DEX-bestand klikt, krijgt u een overzicht te zien van het aantal klassen en methoden die het definieert, en hoeveel verwijzingen het in totaal bevat (het zijn de verwijzingen die meetellen voor de limiet van 64K in een enkel DEX-bestand). In dit voorbeeld bereikt de app bijna de limiet, wat betekent dat MultiDex de klassen in de nabije toekomst in aparte bestanden moet opsplitsen.

U kunt in de packages inzoomen om te zien welke alle referenties gebruiken. In dit geval zien we dat de ondersteuningsbibliotheek en Google Play Services de belangrijkste oorzaken zijn voor deze situatie:

Reference counts per package

Als u MultiDex hebt ingeschakeld en uw app hebt gecompileerd, zult u merken dat er een tweede classes2.dex bestand (en mogelijk classes3.dex, enzovoort). De MultiDex oplossing in de Android gradle plugin zoekt uit welke klassen nodig zijn om uw app te starten en zet ze in het primaire classes.dex bestand, maar in het zeldzame geval dat het niet werkt en u een ClassNotFoundException krijgt, kunt u APK Analyzer gebruiken om de DEX bestanden te inspecteren, en vervolgens de ontbrekende klassen dwingen om in het primaire DEX bestand te worden gezet.

U zult soortgelijke problemen tegenkomen bij het inschakelen van Proguard en het gebruik van klassen of methoden door reflectie of van XML lay-outs. De APK Analyzer kan u helpen bij het controleren of uw Proguard-configuratie correct is, door u eenvoudig te laten controleren of de methoden en klassen die u nodig hebt, aanwezig zijn in de APK en of ze worden hernoemd (geobfluceerd). U kunt er ook voor zorgen dat klassen die u weg wilt hebben ook daadwerkelijk worden verwijderd, en niet uw kostbare aantal referentiemethoden in beslag nemen.

We zijn benieuwd welke andere toepassingen u vindt voor de APK Analyzer en welke andere functies u graag geïntegreerd zou zien in de tool!

Plaats een reactie