Zmniejszanie rozmiaru pliku APK przy użyciu R8 i ProGuard

  • Implementacja R8 i ProGuard w celu usuwania martwego kodu i zaciemniania klas.
  • Korzystanie z pakietów aplikacji Android w celu optymalizacji dostarczania zasobów na podstawie urządzenia użytkownika.
  • Zastępowanie dużych zasobów wydajnymi formatami, takimi jak WebP i Vector Drawables.
  • Konfiguracja modułów dynamicznych w celu pobierania funkcjonalności na żądanie.

Zmniejszanie rozmiaru pliku APK przy użyciu R8 i ProGuard

W miarę jak nasze aplikacje dodają nowe funkcje i stają się coraz bardziej złożone, często zdarza się, że rozmiar pliku końcowego znacznie wzrasta. To poważny problem, ponieważ jeśli aplikacja jest zbyt duża, wielu użytkowników dwa razy się zastanawia, zanim kliknie przycisk instalacji, a co gorsza, rezygnuje z pobierania w połowie. Co więcej, duża aplikacja zajmuje więcej miejsca w telefonie i może ostatecznie wpłynąć na szybkość reakcji systemu.

Aby zapobiec przekształceniu się Twojego projektu w cyfrowy gigant, istnieje kilka strategii, od czyszczenia kodu po optymalizację obrazu. W tym artykule zagłębimy się w wykorzystanie narzędzi takich jak R8 i ProGuard , a także w magię pakietów aplikacji, aby Twoja aplikacja była jak najlżejsza i najszybsza, zapewniając jej bezbłędne działanie nawet na urządzeniach o niższej wydajności.

Zrozumienie, co naprawdę jest ważne w Twojej aplikacji

Zanim zaczniemy, musimy wiedzieć, gdzie znajduje się większość danych. Rozmiar aplikacji zazwyczaj dzieli się na cztery główne bloki. Po pierwsze, mamy kod bajtowy Java lub Kotlin i jego biblioteki, które zazwyczaj stanowią od 30% do 40%. Następnie mamy zasoby, takie jak układy i animacje , o podobnej wielkości. Mamy również biblioteki natywne (C/C++) skompilowane dla różnych architektur (15–25%) i wreszcie zasoby lub pliki RAW (5–15%).

Aby uniknąć zgadywania, najlepiej skorzystać z narzędzia APK Analyzer w Android Studio (wybierając kolejno Kompilacja > Analiza APK). To narzędzie pozwala dokładnie sprawdzić, ile ważą klasy DEX, folder zasobów i biblioteki natywne, umożliwiając porównanie obecnych wersji z poprzednimi i ustalenie, które zmiany spowodowały wzrost rozmiaru pliku. Aby zgłębić ten temat, warto zrozumieć hierarchię plików w systemie Android i sposób ich organizacji.

Oczyszczanie kodu: Przejście z ProGuard do R8

Redukcja kodu jest niewątpliwie najskuteczniejszym sposobem na zmniejszenie liczby bajtów. Właśnie tutaj pojawia się ProGuard i jego współczesny następca, R8. ProGuard przez lata był standardem, dbając o usuwanie nieużywanych klas, pól i metod , optymalizując kod bajtowy i zaciemniając nazwy, aby były krótsze (i trudniejsze do odczytania dla każdego, kto próbuje zhakować kod).

APK, AAB i APKM
Powiązany artykuł:
Zaawansowany przewodnik po różnicach między formatami APK, AAB i APKM w systemie Android: wszystko, co musisz wiedzieć, aby instalować aplikacje jak profesjonalista

Obecnie R8 jest domyślnym kompilatorem i wykonuje wszystko, co robił ProGuard, ale znacznie lepiej i szybciej. R8 implementuje bardziej agresywne wytrząsanie drzewa (tree shake) , łączy klasy z podobnymi funkcjami i optymalizuje wyliczenia, konwertując je na liczby całkowite. Ponadto umożliwia desugowanie, aby korzystać z nowoczesnych funkcji Javy 8 w starszych wersjach Androida.

Konfiguracja techniczna w build.gradle

Aby aktywować te optymalizacje w wersji wydania, należy skonfigurować plik kompilacji, ustawiając minifyEnabled jako prawda i łączenie plików reguł. Konieczne jest użycie proguard-android-optimize.txt aby w pełni wykorzystać optymalizacje. Podstawowy przykład konfiguracji obejmowałby: utrzymywać klasy aplikacji lub te oznaczone @Keep aby zapobiec przypadkowemu usunięciu plików przez R8.

Zarządzanie regułami dla bibliotek zewnętrznych

Czasami R8 jest zbyt wydajny i usuwa kod używany w refleksji, powodując błędy takie jak: ClassNotFoundExceptionDlatego księgarnie takie jak Retrofit, OkHttp lub Gson wymagają określonych zasad.Na przykład w przypadku Gsona kluczowe jest zachowanie nazw pól w modelach danych, aby deserializacja JSON nie zakończyła się niepowodzeniem. Jeśli po zaciemnieniu wystąpią błędy, plik mapowanie.txt To Twój najlepszy sojusznik przy tłumaczeniu śladów stosu i rozpoznawaniu miejsca wystąpienia błędu.

Czy można stworzyć APK nie będąc programistą?
Powiązany artykuł:
Różnice między APKM, APKS i XAPK: Kompletny przewodnik po formatach instalacji Androida

Inteligentna optymalizacja zasobów

Zasoby to często miejsca, w których marnuje się najwięcej miejsca. Prosta, ale skuteczna technika polega na aktywowaniu shrinkResources w pliku build.gradle. Usuwa to pliki, do których nie ma odniesienia w kodzie, choć ważne jest, aby wiedzieć, że jeśli dynamicznie wywołujesz zasób za pomocą getIdentifierBędziesz musiał to zadeklarować w pliku zachowaj.xml żeby nie zniknęło.

Obrazy i grafiki: mniej znaczy więcej

Format PNG zajmuje wiele niepotrzebnych megabajtów. Obecnie zaleca się migrację wszystkich danych do formatu WebP , który oferuje znacznie lepszą kompresję przy zachowaniu jakości. Konwersję można wykonać bezpośrednio w Android Studio, klikając obraz prawym przyciskiem myszy. W przypadku ikon i prostych kształtów idealnie sprawdzają się pliki Vector Drawables ; jeden plik XML zastępuje pięć wersji o różnej gęstości, co upraszcza konserwację i zmniejsza rozmiar pliku.

Ograniczanie liczby języków i gęstości

Wiele bibliotek zewnętrznych zawiera tłumaczenia na 50 języków, których Twoja aplikacja prawdopodobnie nie obsługuje. Aby to naprawić, użyj właściwości resConfigs w defaultConfigokreślając tylko języki, których faktycznie używasz (np. "es", "en"Podobnie możesz ograniczyć gęstość uwzględnionych ekranów, jeśli wiesz, że Twoja grupa docelowa korzysta z nowoczesnych urządzeń, usuwając zasoby ldpi lub mdpi z którego już nikt nie korzysta.

Wyodrębnij APK z aplikacji
Powiązany artykuł:
Kompletny przewodnik po wyodrębnianiu APK z dowolnej aplikacji na Androida: opcje, zabezpieczenia i samouczki

Zaawansowane strategie dystrybucji

Jeśli chcesz zdecydowanie zmniejszyć rozmiar pliku APK, powinieneś zrezygnować z uniwersalnych plików APK i przejść na pakiety aplikacji Android (.aab) . Zamiast wysyłać jeden ogromny plik ze wszystkim, co możliwe, Google Play generuje zoptymalizowany plik APK dla każdego urządzenia. W ten sposób użytkownik z telefonem ARM64 i ekranem xxhdpi pobiera tylko to, czego potrzebuje jego sprzęt , zmniejszając rozmiar pobieranego pliku nawet o 40%.

Dynamiczne moduły funkcyjne i aplikacje błyskawiczne

Nie cały kod musi być dostępny od samego początku. Dzięki modułom funkcji dynamicznych (Dynamic Feature Modules ) możesz oddzielić części aplikacji (takie jak zaawansowany edytor zdjęć czy tryb offline), aby były pobierane tylko wtedy, gdy użytkownik korzysta z tej funkcji. Z drugiej strony, aplikacje błyskawiczne (Instant Apps) pozwalają użytkownikom wypróbować aplikację bez jej instalowania, pobierając niezwykle lekki moduł bazowy za pośrednictwem adresu URL lub przycisku Google Play.

Audyt zależności i ostatecznych szczegółów

Czasami problemem nie jest kod, ale to, co pobierasz z zewnątrz. Biblioteki takie jak Guava czy Jackson mogą być bardzo duże; rozważ zastąpienie ich lżejszymi alternatywami, takimi jak kotlinx.serialization lub Gson . Zaleca się również korzystanie z czcionek do pobrania z Google Fonts zamiast dołączania dużych plików TTF do zasobów, co może zaoszczędzić kilka megabajtów, jeśli używasz wielu wariantów danej czcionki.

Aby zakończyć cykl optymalizacji, pamiętaj, że Android Go to rozwijający się rynek. Jeśli chcesz, aby Twoja aplikacja działała doskonale na urządzeniach z pamięcią RAM mniejszą niż 1 GB, staraj się, aby jej rozmiar nie przekraczał 40 MB. Korzystanie z narzędzia Android Lint do wykrywania osieroconych zasobów i utrzymywanie spójnej procedury czyszczenia sprawi, że Twoja aplikacja będzie wydajna, szybko się zainstaluje i zapewni płynne działanie, niezależnie od mocy urządzenia.

Aktualizacje zabezpieczeń Androida
Powiązany artykuł:
Jak maksymalnie przyspieszyć i zoptymalizować działanie systemu Android: kompletny przewodnik, wskazówki i niezbędne zalecenia

Dodaj jako preferowane źródło w Google