Wykorzystanie analizatora APK

Wojtek Kaliciński

Follow

23 listopada, 2016 – 6 min read

.

Jednym z moich ulubionych ostatnich dodatków do Android Studio jest APK Analyzer, który można znaleźć w górnym menu pod Build → Analyze APK.

Pro-tip: możesz także przeciągnąć i upuścić pliki APK do edytora, aby je otworzyć

APK Analyzer pozwala otworzyć i sprawdzić zawartość dowolnego pliku APK, który masz na komputerze, zbudowanego z lokalnego projektu Android Studio lub pozyskanego z serwera budowania lub innego repozytorium artefaktów. Nie musi być zbudowany z żadnego projektu otwartego w Android Studio i nie potrzebujesz kodu źródłowego dla tego konkretnego APK.

Uwaga: APK Analyzer działa najlepiej z kompilacjami wydania. Jeśli musisz przeanalizować wersję debugowaną swojej aplikacji, upewnij się, że używasz APK, który nie jest oprzyrządowany do Instant Run. Aby go uzyskać, możesz użyć polecenia Build → Build APK. Możesz sprawdzić, czy otworzyłeś APK z oprzyrządowaniem Instant Run, sprawdzając obecność pliku instant-run.zip w archiwum.

Używanie analizatora APK jest świetnym sposobem na przeszukiwanie plików APK i poznanie ich struktury, sprawdzenie zawartości pliku przed wydaniem lub usunięcie niektórych typowych problemów, w tym rozmiaru APK i problemów z DEX.

Analizator APK może dostarczyć wielu przydatnych informacji na temat rozmiaru aplikacji. Na górze ekranu możesz zobaczyć Raw File Size, który jest tylko rozmiarem APK na dysku. Rozmiar pobierania pokazuje szacunkowe dane, które będą używane do pobrania aplikacji, biorąc pod uwagę kompresję zastosowaną przez Sklep Play.

Lista plików i folderów jest posortowana według całkowitego rozmiaru w porządku malejącym. To sprawia, że świetnie nadaje się do identyfikacji nisko wiszących owoców optymalizacji rozmiaru APK. Za każdym razem, gdy drążysz w dół do folderu, możesz zobaczyć zasoby i inne jednostki, które zajmują najwięcej miejsca w APK.

Zasoby posortowane w kolejności malejącej według rozmiaru

W tym przykładzie, podczas badania APK pod kątem możliwych redukcji rozmiaru, byłem w stanie od razu zauważyć, że 3 klatkowa animacja PNG jest największą rzeczą w naszych zasobach do wyciągnięcia, ważącą 1.5MB, i to tylko dla gęstości xxhdpi!

Ponieważ te obrazy wyglądają jak idealni kandydaci do przechowywania jako wektory, znaleźliśmy pliki źródłowe dla dzieła sztuki i zaimportowaliśmy je jako VectorDrawables używając nowego wsparcia PSD w narzędziu importu Vector Asset w Android Studio 2.2.

Przechodząc przez ten sam proces dla drugiej pozostałej animacji (instruction_touch_*.png) i usuwając te pliki PNG we wszystkich gęstościach, byliśmy w stanie zaoszczędzić ponad 5MB. Aby zachować kompatybilność wsteczną, użyliśmy VectorDrawableCompat z biblioteki wsparcia.

Patrząc na inne foldery zasobów, łatwo było zauważyć kilka nieskompresowanych plików WAV, które mogły zostać przekonwertowane na OGG, co oznaczało jeszcze większe oszczędności bez dotykania linii kodu.

Przeglądanie innych folderów w APK

Następnym na liście rzeczy do sprawdzenia był folder lib/, który zawiera natywne biblioteki dla trzech obsługiwanych przez nas ABI.

Podjęta została decyzja o użyciu wsparcia APK splits w naszym buildzie Gradle, aby stworzyć oddzielne wersje aplikacji dla każdego ABI.

Szybko przejrzałem następny AndroidManifest.xml i zauważyłem, że w <aplikacji> brakuje atrybutu android:extractNativeLibs. Ustawienie tego atrybutu na false może zaoszczędzić trochę miejsca na urządzeniu, ponieważ zapobiega kopiowaniu natywnych bibliotek z APK do systemu plików. Jedynym wymaganiem jest to, aby pliki były wyrównane do strony i przechowywane w postaci nieskompresowanej wewnątrz APK, co jest obsługiwane przez nowy paker we wtyczce Android Gradle w wersji 2.2.0+.

Pełny AndroidManifest.xml widziany w APK Analyzer

Po wprowadzeniu tych modyfikacji, byłem ciekaw jak nowa wersja aplikacji wypada w porównaniu do poprzedniej. Aby to zrobić, sprawdziłem źródło z git commit, od którego zacząłem, skompilowałem APK i zapisałem go w innym folderze. Następnie użyłem funkcji Porównaj z…, aby zobaczyć zestawienie różnic w rozmiarze pomiędzy starym i nowym buildem.

Porównanie APK – dostęp przez przycisk w prawym górnym rogu

Dokonaliśmy sporego postępu w kwestii zasobów i natywnych bibliotek, oszczędzając w sumie 17MB przy bardzo niewielkich zmianach w aplikacji. Widzę jednak, że nasz rozmiar DEX uległ regresowi, z classes2.dex rosnącym o 400KB.

Debugging DEX issues

W tym przypadku różnica wynikała z aktualizacji naszych zależności do nowszych wersji i dodania nowych bibliotek. Proguard i Multidex były już włączone dla naszych buildów, więc nie ma wiele co można zrobić z naszym rozmiarem DEX. Mimo to, APK analyzer jest świetnym narzędziem do debugowania wszelkich problemów z tą konfiguracją, szczególnie gdy włączasz Multidex lub Proguard dla swojego projektu po raz pierwszy.

Poznanie zawartości klas.dex

Kiedy klikniesz na dowolny plik DEX, zobaczysz podsumowanie, ile klas i metod definiuje oraz ile zawiera odwołań (to właśnie odwołania liczą się do limitu 64K w pojedynczym pliku DEX). Na tym zrzucie ekranu aplikacja jest bliska osiągnięcia limitu, co oznacza, że będzie potrzebowała MultiDex do podzielenia klas na osobne pliki w najbliższej przyszłości.

Możesz drążyć w dół do pakietów, aby zobaczyć, które z nich wykorzystują wszystkie referencje. W tym przypadku widzimy, że biblioteka Support i Usługi Google Play są głównymi przyczynami tej sytuacji:

Liczba referencji na pakiet

Po włączeniu MultiDex i skompilowaniu aplikacji, zauważysz drugi plik classes2.dex (i ewentualnie classes3.dex, i tak dalej). Rozwiązanie MultiDex we wtyczce Android gradle określa, które klasy są potrzebne do uruchomienia aplikacji i umieszcza je w podstawowym pliku classes.dex, ale w rzadkich przypadkach, gdy to nie działa i otrzymujesz wyjątek ClassNotFoundException, możesz użyć APK Analyzer do sprawdzenia plików DEX, a następnie wymusić umieszczenie brakujących klas w podstawowym pliku DEX.

Podobne problemy napotkasz, gdy włączysz Proguard i użyjesz klas lub metod przez refleksję lub z układów XML. APK Analyzer może pomóc w sprawdzeniu poprawności konfiguracji Proguard, pozwalając łatwo sprawdzić czy metody i klasy, których potrzebujesz są obecne w APK i czy ich nazwy są zmieniane (obfuscated). Możesz również upewnić się, że klasy, które chcesz usunąć, zostały faktycznie usunięte i nie zajmują cennej liczby metod referencyjnych.

Ciekawi nas, jakie inne zastosowania znajdziesz dla APK Analyzer i jakie inne funkcje chciałbyś zobaczyć zintegrowane z tym narzędziem!

Dodaj komentarz