Få mest muligt ud af APK analyzer

Wojtek Kaliciński

Follow

23. nov, 2016 – 6 min read

En af mine foretrukne nylige tilføjelser til Android Studio er APK Analyzer, som du kan finde i topmenuen under Build → Analyze APK.

Pro-tip: du kan også trække og slippe APK-filer ind i editoren for at åbne dem

APK Analyzer lader dig åbne og inspicere indholdet af enhver APK-fil, du har på din computer, enten bygget fra dit lokale Android Studio-projekt eller erhvervet fra din buildserver eller et andet artefaktopbevaringssted. Den behøver ikke at være bygget fra et projekt, du har åbnet i Android Studio, og du har ikke brug for kildekoden til den pågældende APK.

Bemærk: APK Analyzer fungerer bedst med udgivelsesbygninger. Hvis du har brug for at analysere et debug-build af din app, skal du sikre dig, at du bruger en APK, der ikke er instrumenteret til Instant Run. For at få den kan du bruge kommandoen Build → Build APKcommand. Du kan se, om du har åbnet en APK, der er instrumenteret til Instant Run, ved at kontrollere tilstedeværelsen af en instant-run.zip-fil i arkivet.

Anvendelse af APK-analysatoren er en god måde at rode rundt i APK-filer og lære om deres struktur, verificere filindholdet før frigivelse eller fejlfinde nogle almindelige problemer, herunder APK-størrelse og DEX-problemer.

Apk-analysatoren kan give dig en masse nyttig og brugbar information om app-størrelsen. Øverst på skærmen kan du se den rå filstørrelse, som blot er APK-størrelsen på disken. Downloadstørrelsen viser et skøn over, hvor mange data der bruges til at downloade din app ved at tage højde for den komprimering, der anvendes af Play Store.

Listen over filer og mapper er sorteret efter samlet størrelse i faldende rækkefølge. Dette gør den god til at identificere de lavt hængende frugter for optimering af APK-størrelsen. Hver gang du borer ned i en mappe, kan du se de ressourcer og andre enheder, der optager mest plads i din APK.

Ressourcer sorteret i faldende orden efter størrelse

I dette eksempel kunne jeg, da jeg undersøgte en APK for mulige størrelsesreduktioner, straks bemærke, at en PNG-animation med 3 billeder er den største ting i vores tegningsbare ressourcer, der vejer 1.5 MB, og det er kun for xxhdpi-densiteten!

Da disse billeder ligner perfekte kandidater til lagring som vektorer, fandt vi kildefilerne til artwork og importerede dem som VectorDrawables ved hjælp af den nye PSD-understøttelse i Vector Asset-importværktøjet i Android Studio 2.2.

Ved at gennemgå den samme proces for den anden resterende animation (instruction_touch_*.png) og fjerne disse PNG-filer på tværs af alle densiteter kunne vi spare over 5 MB. For at bevare bagudkompatibilitet brugte vi VectorDrawableCompat fra supportbiblioteket.

Ved at kigge på andre ressourcemapper var det nemt at få øje på nogle ukomprimerede WAV-filer, der kunne konverteres til OGG, hvilket betød endnu flere besparelser uden at røre en linje kode.

Besøg i andre mapper i APK’en

Næste punkt på listen over ting, der skulle kontrolleres, var lib/-mappen, som indeholder native biblioteker for de tre ABI’er, som vi understøtter.

Det blev besluttet at bruge APK splits-understøttelse i vores Gradle-bygning for at oprette separate versioner af appen for hver ABI.

Jeg kiggede hurtigt på AndroidManifest.xml næste og bemærkede, at <application> mangler attributten android:extractNativeLibs. Hvis du indstiller denne attribut til false, kan du spare noget plads på enheden, da det forhindrer kopiering af de native biblioteker fra APK’en til filsystemet. Det eneste krav er, at filerne er sidejusterede og gemt ukomprimeret i APK’en, hvilket understøttes med den nye pakker i Android Gradle-pluginversionen 2.2.0+.

Den fulde AndroidManifest.xml som vist i APK Analyzer

Når jeg havde foretaget disse ændringer, var jeg nysgerrig efter at se, hvordan den nye version af appen er sammenlignet med den tidligere version. For at gøre det tjekkede jeg kilden fra det git commit, som jeg startede med, kompilerede APK’en og gemte den i en anden mappe. Derefter brugte jeg funktionen Sammenlign med… for at se en opdeling af størrelsesforskellene mellem den gamle og den nye builds.

APK-sammenligning – få adgang til den via knappen øverst til højre

Vi gjorde store fremskridt med ressourcerne og de native biblioteker og sparede i alt 17 MB med meget få ændringer i appen. Jeg kan dog se, at vores DEX-størrelse gik tilbage, idet classes2.dex voksede med 400 KB.

Debugging DEX-problemer

I dette tilfælde kom forskellen fra opgradering af vores afhængigheder til nyere versioner og tilføjelse af nye biblioteker. Proguard og Multidex var allerede aktiveret for vores builds, så der er ikke meget, der kan gøres ved vores DEX-størrelse. Alligevel er APK analyzer et godt værktøj til at debugge eventuelle problemer med denne opsætning, især når du aktiverer Multidex eller Proguard for dit projekt for første gang.

Udforskning af indholdet af klasser.dex

Når du klikker på en DEX-fil, vil du se en oversigt over, hvor mange klasser og metoder den definerer, og hvor mange referencer den i alt indeholder (det er referencer, der tæller med i forhold til 64K-grænsen i en enkelt DEX-fil). I dette eksempelskærmbillede er appen lige ved at nå grænsen, hvilket betyder, at den vil få brug for MultiDex til at opdele klasserne i separate filer i den nærmeste fremtid.

Du kan bore ned i pakkerne for at se, hvilke pakker der bruger alle referencerne. I dette tilfælde kan vi se, at Support-biblioteket og Google Play Services er hovedårsagerne til denne situation:

Referencetællinger pr. pakke

Når du har aktiveret MultiDex og kompileret din app, vil du bemærke en anden klasser2.dex-fil (og muligvis classes3.dex og så videre). MultiDex-løsningen i Android gradle-plugin’et finder ud af, hvilke klasser der er nødvendige for at starte din app, og lægger dem i den primære classes.dex-fil, men i det sjældne tilfælde, hvor det ikke virker, og du får en ClassNotFoundException, kan du bruge APK Analyzer til at inspicere DEX-filerne og derefter tvinge de manglende klasser til at blive lagt i den primære DEX-fil.

Du vil støde på lignende problemer, når du aktiverer Proguard og bruger klasser eller metoder ved refleksion eller fra XML-layouts. APK Analyzer kan hjælpe dig med at verificere, at din Proguard-konfiguration er korrekt, ved at du nemt kan kontrollere, om de metoder og klasser, du har brug for, er til stede i APK’en, og om de bliver omdøbt (obfuscated). Du kan også sikre dig, at de klasser, du ønsker fjernet, rent faktisk er fjernet og ikke optager dit dyrebare antal referencemetoder.

Vi er nysgerrige efter at høre, hvilke andre anvendelsesmuligheder du finder for APK Analyzer, og hvilke andre funktioner du gerne vil se integreret i værktøjet!

Skriv en kommentar