Zmniejsz rozmiar aplikacji

Użytkownicy często unikają pobierania aplikacji, które wydają się za duże, zwłaszcza na rynkach wschodzących, urządzenia łączą się z sieciami 2G i 3G o specjalnej jakości lub korzystają z abonamentów z limitami danych. Na tej stronie opisujemy jak zmniejszyć rozmiar pobieranej aplikacji, aby więcej użytkowników mogło ją pobrać.

Przesyłanie aplikacji za pomocą pakietów Android App Bundle

Prześlij aplikację jako pakiet Android App Bundle, aby od razu zmniejszyć jej rozmiar podczas publikowania w Google Play. Pakiet Android App Bundle to format przesyłania, który zawiera cały skompilowany kod i zasoby aplikacji, ale odkłada generowanie i podpisywanie pliku APK na czas publikacji w Google Play.

Model udostępniania aplikacji w Google Play wykorzystuje następnie Twój pakiet aplikacji do generowania i udostępniania zoptymalizowanych plików APK dla konfiguracji urządzenia każdego użytkownika, dzięki czemu pobiera on tylko kod i zasoby potrzebne uruchom aplikację. Nie musisz tworzyć i podpisywać wielu plików APK ani zarządzać nimi, by obsługiwać różne urządzenia. a użytkownicy pobierają pliki mniejsze i lepiej zoptymalizowane.

Google Play stosuje ograniczenie rozmiaru skompresowanego pliku do pobrania na poziomie 200 MB w przypadku aplikacji publikowanych w pakietach aplikacji. Większe rozmiary są możliwe dzięki funkcjom Play Feature Delivery i Play Asset Delivery, ale zwiększenie rozmiaru aplikacji może negatywnie wpłynąć na liczbę instalacji i liczba odinstalowań. Dlatego zalecamy stosowanie się do wskazówek opisanych na tej stronie, aby jak najbardziej zmniejszyć rozmiar pliku do pobrania aplikacji.

Informacje o strukturze plików APK

Zanim zmniejszysz rozmiar aplikacji, warto poznać strukturę pliku APK. Plik APK składa się z archiwum ZIP zawierającego wszystkie pliki, z których składa się aplikacja. Te pliki obejmują pliki klas Java, pliki zasobów i plik zawierający skompilowane zasoby.

Plik APK zawiera te katalogi:

  • META-INF/: zawiera podpis CERT.SF i CERT.RSA oraz plik manifestu MANIFEST.MF.
  • assets/: zawiera zasoby aplikacji, które aplikacja może pobrać za pomocą AssetManager obiektu.
  • res/: zawiera zasoby, które nie są zgrupowane w resources.arsc.
  • lib/: zawiera skompilowany kod specyficzny dla warstwy programowej procesora. Katalog ten zawiera podkatalog dla każdego typu platformy, np. armeabi, armeabi-v7a, arm64-v8a, x86, x86_64mips.

Plik APK zawiera też te pliki: Wymagany jest tylko element AndroidManifest.xml:

  • resources.arsc: zawiera skompilowane zasoby. Ten plik zawiera treść XML ze wszystkich konfiguracji folderu res/values/. Narzędzie do tworzenia pakietów wyodrębnia XML, kompiluje ją do postaci binarnej i archiwizuje. Te treści zawierają język ciągi tekstowe i style, a także ścieżki do treści, które nie są uwzględnione bezpośrednio w tagu resources.arsc, takie jak pliki układu i obrazy.
  • classes.dex: zawiera klasy skompilowane w formacie pliku DEX akceptowanym przez np. Dalvik czy ART.
  • AndroidManifest.xml: zawiera podstawowy plik manifestu Androida. Ten plik zawiera listę nazwa, wersja, prawa dostępu i użyte pliki biblioteki aplikacji. Plik korzysta z interfejsu binarnego formatu XML.

Zmniejsz liczbę i rozmiar zasobów

Rozmiar pliku APK ma wpływ na to, jak szybko się wczytuje, ile pamięci wykorzystuje i jak zużywa dużo energii. Możesz zmniejszyć plik APK, zmniejszając liczbę i rozmiar zawartych w nim zasobach. Możesz na przykład usunąć zasoby, których aplikacja już nie używa, oraz zastąpić pliki graficzne skalowalnymi obiektami Drawable. W tej sekcji omawiamy te metody oraz inne sposoby zmniejszania liczby zasobów w aplikacji, aby zmniejszyć ogólny rozmiar pliku APK.

Usuń nieużywane zasoby

Narzędzie lint – statyczny analizator kodu dostępne w Android Studio – wykrywa w folderze res/ zasoby, które Twój kod nie odwołuje się do. Gdy narzędzie lint wykryje w Twoim projekcie potencjalnie niewykorzystany zasób, wyświetli komunikat podobny do tego:

res/layout/preferences.xml: Warning: The resource R.layout.preferences appears
    to be unused [UnusedResources]

Biblioteki dodane do kodu mogą zawierać nieużywane zasoby. Gradle może automatycznie usuń zasoby w Twoim imieniu, jeśli włączysz funkcję shrinkResources w: build.gradle.kts aplikacji.

android {
    // Other settings.

    buildTypes {
        getByName("release") {
            minifyEnabled = true
            shrinkResources = true
            proguardFiles(getDefaultProguardFile('proguard-android.txt'), "proguard-rules.pro")
        }
    }
}
android {
    // Other settings.

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

Aby używać funkcji shrinkResources, włącz zmniejszanie kodu. Podczas procesu kompilacji R8 najpierw usuwa nieużywany kod. Następnie wtyczka Androida do obsługi Gradle usuwa nieużywane zasoby.

Więcej informacji o skracaniu kodu i zasobów oraz innych sposobach zmniejszania rozmiaru pliku APK w Android Studio znajdziesz w artykule Skracanie, zaciemnianie i optymalizowanie aplikacji.

W pliku Android Gradle Plugin w wersji 7.0 lub nowszej możesz deklarować konfiguracje obsługiwane przez aplikację. Gradle przekazuje te informacje do systemu kompilacji za pomocą resourceConfigurations smak i opcję defaultConfig. Następnie system kompilacji uniemożliwia zasobom w pliku APK nie pojawiają się inne nieobsługiwane konfiguracje, co zmniejsza jego rozmiar. Więcej na temat tej funkcji, zobacz Usuń nieużywaną alternatywę .

Minimalizuj wykorzystanie zasobów z bibliotek

Podczas tworzenia aplikacji na Androida zwykle używasz zewnętrznych bibliotek, aby zwiększyć użyteczność i wszechstronność aplikacji. Możesz na przykład wybrać AndroidX. aby poprawić wygodę użytkowników na starszych urządzeniach. Możesz też użyć Usługi Google Play do pobrania automatyczne tłumaczenia tekstu w aplikacji.

Jeśli biblioteka jest przeznaczona do serwera lub komputera, może zawierać wiele obiektów i metod, których Twoja aplikacja nie potrzebuje. Aby uwzględnić tylko te części biblioteki, których potrzebuje Twoja aplikacja, możesz edytować pliki biblioteki, jeśli licencja pozwala na modyfikowanie biblioteki. Możesz też użyć alternatywnej biblioteki zoptymalizowanej pod kątem urządzeń mobilnych, aby dodać do aplikacji określone funkcje.

Natywne dekodowanie animowanego obrazu

W Androidzie 12 (poziom interfejsu API 31) pakiet NDK Interfejs API ImageDecoder jest rozszerzony w celu zdekodowania wszystkich klatek i danych o czasie pochodzących z obrazów w animowanych formatach GIF i WebP.

Aby kontynuować, używaj ImageDecoder zamiast bibliotek innych firm zmniejsz rozmiar plików APK i ciesz się korzyściami w przyszłości aktualizacji związanych z bezpieczeństwem i wydajnością.

Więcej informacji o interfejsie API ImageDecoder znajdziesz tutaj: API reference oraz przykład w GitHubie.

Obsługują tylko określone wartości gęstości.

Android obsługuje różne gęstości ekranu, na przykład:

  • ldpi
  • mdpi
  • tvdpi
  • hdpi
  • xhdpi
  • xxhdpi
  • xxxhdpi

Mimo że Android obsługuje poprzednie gęstości, nie musisz eksportować zrastrowanych do różnych gęstości.

Jeśli wiesz, że tylko niewielki odsetek Twoich użytkowników ma urządzenia o określonej gęstości, zastanów się, czy musisz uwzględnić te gęstości w aplikacji. Jeśli nie dodasz zasobów do określonej gęstości ekranu, Android automatycznie skaluje istniejące zasoby, które zostały pierwotnie zaprojektowane dla innych gęstości ekranu.

Jeśli Twoja aplikacja potrzebuje tylko przeskalowanych obrazów, możesz zaoszczędzić jeszcze więcej miejsca, tworząc jedną wersję obraz w kolekcji drawable-nodpi/. Zalecamy uwzględnienie co najmniej xxhdpi wariantu obrazu w aplikacji.

Więcej informacji o gęstości ekranu znajdziesz tutaj: Rozmiary i gęstość ekranu

Używanie obiektów do rysowania

Niektóre obrazy nie wymagają zasobu obrazu statycznego. Platforma może zamiast tego rysować obraz dynamicznie w czasie działania. Drawable obiektów lub <shape> in XML – mogą zajmować niewielką ilość miejsca w pakiecie APK. Dodatkowo XML Drawable obiekty generują obrazy monochromatyczne zgodne z wytycznymi Material Design.

Ponowne wykorzystywanie zasobów

Możesz dołączyć osobny zasób dla odmian zdjęcia, np. barwione, zacienione obróconych wersji tego samego obrazu. Zalecamy jednak ponowne używanie tego samego zestawu zasobów i dostosowywanie go w razie potrzeby w czasie wykonywania.

Android udostępnia kilka narzędzi, które pozwalają zmienić kolor zasobu. Mogą to być Atrybuty android:tint i tintMode.

Możesz też pominąć zasoby, które są tylko rotacyjnym odpowiednikiem innego zasobu. Poniżej Fragment kodu to przykład „kciuka w górę” w „kciuk w dół”, a potem przestawiając na środku zdjęcia i obracając je o 180 stopni:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_thumb_up"
    android:pivotX="50%"
    android:pivotY="50%"
    android:fromDegrees="180" />

Renderowanie z kodu

Rozmiar pliku APK możesz też zmniejszyć, programowo renderując obrazy. Renderowanie proceduralne zwalnia miejsce, bo w pakiecie APK nie przechowujesz już pliku graficznego.

Kompresowanie plików PNG

Narzędzie aapt może zoptymalizować zasoby obrazu umieszczone w lokalizacji res/drawable/ z bezstratną kompresją podczas budowania. Narzędzie aapt może na przykład: przekonwertować plik PNG w prawdziwym kolorze, który nie wymaga więcej niż 256 kolorów, na 8-bitowy plik PNG z kolorem. paletę kolorów. Dzięki temu obraz będzie miał taką samą jakość, ale mniejszy rozmiar pamięci.

aapt ma te ograniczenia:

  • Narzędzie aapt nie zmniejsza plików PNG zawarte w asset/ folderu Dysku.
  • Pliki obrazów mogą mieć maksymalnie 256 kolorów, aby można je było zoptymalizować za pomocą narzędzia aapt .
  • Narzędzie aapt może zwiększać rozmiar już skompresowanych plików PNG. Aby temu zapobiec, możesz użyć flagi isCrunchPngs, aby wyłączyć ten proces w przypadku plików PNG:
  •     buildTypes.all { isCrunchPngs = false }
        
        buildTypes.all { isCrunchPngs = false }
        

Kompresuj pliki PNG i JPEG

Możesz zmniejszyć rozmiar pliku PNG bez utraty jakości obrazu za pomocą takich narzędzi jak pngcrush, pngQuantity lub zopflipng. Wszystkie te narzędzia mogą zmniejszyć rozmiar pliku PNG, zachowując przy tym jakość obrazu.

Szczególnie skuteczne jest narzędzie pngcrush. To narzędzie iteruje filtry PNG oraz zlib (Deflate), wykorzystując każdą kombinację filtrów i parametrów do skompresowania obrazu. Następnie wybiera konfigurację, która generuje najmniejsze skompresowane dane wyjściowe.

Do skompresowania plików JPEG możesz użyć narzędzi takich jak packJPG czy guetzli.

Użyj formatu pliku WebP

Zamiast pliku PNG lub JPEG możesz też użyć pliku WebP. WebP zapewnia kompresję stratną i przejrzystość, jak JPG i PNG. niż JPEG czy PNG.

Za pomocą Android Studio możesz przekonwertować istniejące obrazy BMP, JPG, PNG lub GIF statyczny do formatu WebP. Więcej informacji znajdziesz w artykule Tworzenie obrazów WebP.

Używanie grafik wektorowych

Grafiki wektorowej możesz używać do tworzenia ikon niezależnych od rozdzielczości i innych skalowanych multimediów. Dzięki tym grafikom możesz znacznie zmniejszyć ślad APK. Obrazy wektorowe są reprezentowane w Android jako VectorDrawable obiektów. W przypadku obiektu VectorDrawable plik o rozmaju 100 bajtów może wygenerować ostry obraz o rozmiarze ekranu.

Renderowanie każdego z nich zajmuje jednak znacznie więcej czasu. VectorDrawable obiekt, a większe obrazy pojawią się na ekranie jeszcze dłużej. Dlatego rozważ użycie grafik wektorowych tylko wtedy, gdy wyświetlasz małe obrazy.

Więcej informacji o pracy z obiektami VectorDrawable znajdziesz w artykule Elementy rysowalne.

Używaj grafiki wektorowej jako animowanych obrazów

Nie używaj AnimationDrawable do tworzenia animacji klatka po klatce, bo wymaga to dołączenia osobnej mapy bitowej. dla każdej klatki animacji, co znacznie zwiększa rozmiar pakietu APK.

Zamiast tego użyj AnimatedVectorDrawableCompat, aby tworzyć animowane wektory drawable.

Ogranicz kod natywny i kod Java

Korzystając z poniższych metod, możesz zmniejszyć rozmiar bazy kodu Java i natywnej w .

Usuń zbędny wygenerowany kod

Pamiętaj, aby zapoznać się z zawartością każdego kodu, który jest generowany automatycznie. Przykład: wiele narzędzi buforujących protokół generuje nadmierną liczbę metod i klas, które mogą spowodować 3 razy większy rozmiar aplikacji.

Unikaj enumeracji

Pojedyncze wyliczenie może dodać około 1,0–1,4 KB do pliku classes.dex aplikacji. Te że dodatkowe dodatki można szybko akumulować w przypadku złożonych systemów lub bibliotek udostępnionych. Jeśli to możliwe, za pomocą adnotacji @IntDef i zmniejszania kodu aby usunąć wyliczenia i przekonwertować je na liczby całkowite. Konwersja tego typu zachowuje wszystkie związane z bezpieczeństwem typów wyliczeniowych.

Zmniejszanie rozmiaru natywnych plików binarnych

Jeśli Twoja aplikacja używa kodu natywnego i pakietu Android NDK, możesz też zmniejszyć rozmiar wersji dzięki optymalizacji kodu. Dwie przydatne metody to usuwanie symboli debugowania oraz bez wyodrębniania bibliotek natywnych.

Usuń symbole debugowania

Korzystanie z symboli debugowania ma sens, jeśli aplikacja jest w trakcie tworzenia i nadal wymaga debugowania. Użyj narzędzie arm-eabi-strip dostępne w pakiecie Android NDK w celu usunięcia zbędnych elementów debugowania z bibliotek natywnych. Później możesz skompilować kompilację wersji.

Unikaj wyodrębniania bibliotek natywnych

Podczas kompilowania wersji aplikacji przeznaczonej do publikacji skompresowane pliki .so zapakuj w pliku APK, ustawiając w pliku build.gradle.kts aplikacji wartość useLegacyPackaging na false. Wyłączenie tej flagi zapobiega PackageManager od Kopiowanie .so plików z pakietu APK do systemu plików podczas instalacji. Dzięki temu aktualizacje aplikacji będą mniejsze.

Utrzymywanie wielu uproszczonych plików APK

Plik APK może zawierać treści, które użytkownicy pobierają, ale nigdy nie używają, np. dodatkowe języki według gęstości ekranu. Aby ograniczyć ilość pobrań do minimum, prześlij aplikację na Google Play za pomocą pakietów Android App Bundle. Przesyłanie pakietów aplikacji pozwala Google Google Play generuje i udostępnia zoptymalizowane pliki APK dostosowane do konfiguracji urządzenia każdego użytkownika, aby pobierał tylko: kod i zasoby potrzebne do uruchomienia aplikacji. Nie musisz tworzyć, podpisywać i zarządzać wieloma na różne urządzenia, a użytkownicy otrzymują mniejsze i lepiej zoptymalizowane pliki do pobrania.

Jeśli nie publikujesz w Google Play, możesz podzielić aplikację na kilka plików APK. różnią się takimi czynnikami jak rozmiar ekranu czy obsługa tekstury GPU.

Gdy użytkownik pobierze Twoją aplikację, urządzenie otrzyma odpowiedni plik APK na podstawie funkcje i ustawienia. Dzięki temu urządzenia nie otrzymują zasobów dla funkcji, których nie mają. Jeśli na przykład użytkownik ma urządzenie hdpi, nie potrzebuje zasobów xxxhdpi, które można uwzględnić w przypadku urządzeń z wyświetlaczami o wyższej gęstości.

Więcej informacji znajdziesz w artykule Tworzenie wielu elementów Pliki APK i obsługę wielu plików APK.