Пользователи часто избегают загрузки приложений, которые кажутся слишком большими, особенно на развивающихся рынках, где устройства подключаются к нестабильным сетям 2G и 3G или работают по тарифным планам с ограничениями по объему данных. На этой странице описывается, как уменьшить размер загрузки вашего приложения, что позволит большему количеству пользователей загрузить ваше приложение.
Загрузите свое приложение с помощью Android App Bundles
Загрузите свое приложение как Android App Bundle , чтобы немедленно сохранить размер приложения при публикации в Google Play. Android App Bundle — это формат загрузки, который включает весь скомпилированный код и ресурсы вашего приложения, но откладывает генерацию APK и подписание в Google Play.
Модель обслуживания приложений Google Play затем использует ваш пакет приложений для генерации и обслуживания оптимизированных APK для конфигурации устройства каждого пользователя, чтобы они загружали только тот код и ресурсы, которые им нужны для запуска вашего приложения. Вам не нужно создавать, подписывать и управлять несколькими APK для поддержки разных устройств, а пользователи получают меньшие, более оптимизированные загрузки.
Google Play устанавливает ограничение на размер сжатой загрузки в 200 МБ для приложений, опубликованных с помощью пакетов приложений. Большие размеры возможны с использованием Play Feature Delivery и Play Asset Delivery, но увеличение размера вашего приложения может негативно повлиять на успешность установки и увеличить количество удалений, поэтому мы рекомендуем вам применить рекомендации, описанные на этой странице, чтобы максимально уменьшить размер загрузки вашего приложения.
Понять структуру APK
Прежде чем уменьшать размер приложения, полезно понять структуру APK приложения. Файл APK состоит из ZIP-архива, который содержит все файлы, составляющие ваше приложение. Эти файлы включают файлы классов Java, файлы ресурсов и файл, содержащий скомпилированные ресурсы.
APK содержит следующие каталоги:
-
META-INF/
: содержит файлы подписейCERT.SF
иCERT.RSA
, а также файл манифестаMANIFEST.MF
. -
assets/
: содержит активы приложения, которые приложение может извлечь с помощью объектаAssetManager
. -
res/
: содержит ресурсы, которые не скомпилированы вresources.arsc
. -
lib/
: содержит скомпилированный код, специфичный для программного слоя процессора. Этот каталог содержит подкаталог для каждого типа платформы, напримерarmeabi
,armeabi-v7a
,arm64-v8a
,x86
,x86_64
иmips
.
APK также содержит следующие файлы. Обязательным является только AndroidManifest.xml
:
-
resources.arsc
: содержит скомпилированные ресурсы. Этот файл содержит XML-контент из всех конфигураций папкиres/values/
. Инструмент упаковки извлекает этот XML-контент, компилирует его в двоичную форму и архивирует контент. Этот контент включает в себя языковые строки и стили, а также пути к контенту, который не включен напрямую в файлresources.arsc
, например, файлы макетов и изображения. -
classes.dex
: содержит классы, скомпилированные в формате файла DEX, понимаемом виртуальной машиной Dalvik или ART. -
AndroidManifest.xml
: содержит основной файл манифеста Android. В этом файле перечислены имя, версия, права доступа и ссылочные файлы библиотеки приложения. Файл использует двоичный формат XML Android.
Уменьшить количество и размер ресурсов
Размер вашего APK влияет на то, как быстро загружается ваше приложение, сколько памяти оно использует и сколько энергии оно потребляет. Вы можете уменьшить свой APK, уменьшив количество и размер содержащихся в нем ресурсов. В частности, вы можете удалить ресурсы, которые ваше приложение больше не использует, и вы можете использовать масштабируемые объекты Drawable
вместо файлов изображений. В этом разделе обсуждаются эти методы и другие способы, с помощью которых вы можете уменьшить ресурсы в своем приложении, чтобы уменьшить общий размер вашего APK.
Удалить неиспользуемые ресурсы
Инструмент lint
— статический анализатор кода, включенный в Android Studio — обнаруживает ресурсы в папке res/
, на которые не ссылается ваш код. Когда инструмент lint
обнаруживает потенциально неиспользуемый ресурс в вашем проекте, он выводит сообщение, подобное следующему примеру:
res/layout/preferences.xml: Warning: The resource R.layout.preferences appears to be unused [UnusedResources]
Библиотеки, которые вы добавляете в свой код, могут включать неиспользуемые ресурсы. Gradle может автоматически удалять ресурсы от вашего имени, если вы включите shrinkResources
в файле build.gradle.kts
вашего приложения.
Котлин
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' } } }
Чтобы использовать shrinkResources
, включите сжатие кода. В процессе сборки R8 сначала удаляет неиспользуемый код. Затем плагин Android Gradle удаляет неиспользуемые ресурсы.
Дополнительную информацию о сокращении кода и ресурсов, а также о других способах, которыми Android Studio уменьшает размер APK, см . в разделе Сжатие, обфускация и оптимизация приложения .
В Android Gradle Plugin 7.0 и более поздних версиях вы можете объявить конфигурации, которые поддерживает ваше приложение. Gradle передает эту информацию в систему сборки с помощью resourceConfigurations
и параметра defaultConfig
. Затем система сборки предотвращает появление ресурсов из других неподдерживаемых конфигураций в APK, уменьшая размер APK. Для получения дополнительной информации об этой функции см. Удаление неиспользуемых альтернативных ресурсов .
Минимизируйте использование ресурсов библиотек
При разработке приложения Android вы обычно используете внешние библиотеки для улучшения удобства использования и универсальности вашего приложения. Например, вы можете ссылаться на AndroidX , чтобы улучшить пользовательский опыт на более ранних устройствах, или вы можете использовать Google Play Services для получения автоматических переводов текста в вашем приложении.
Если библиотека предназначена для сервера или рабочего стола, она может включать много объектов и методов, которые не нужны вашему приложению. Чтобы включить только те части библиотеки, которые нужны вашему приложению, вы можете редактировать файлы библиотеки, если лицензия позволяет вам изменять библиотеку. Вы также можете использовать альтернативную, дружественную к мобильным устройствам библиотеку, чтобы добавить определенную функциональность в ваше приложение.
Декодирование собственных анимированных изображений
В Android 12 (уровень API 31) API NDK ImageDecoder
расширен для декодирования всех кадров и данных о времени из изображений, использующих анимированные форматы файлов GIF и анимированные WebP.
Используйте ImageDecoder
вместо сторонних библиотек, чтобы еще больше уменьшить размер APK и воспользоваться преимуществами будущих обновлений, связанных с безопасностью и производительностью.
Более подробную информацию об API ImageDecoder
можно найти в API reference
и примере на GitHub .
Поддерживает только определенные плотности
Android поддерживает различные плотности экрана, например:
-
ldpi
-
mdpi
-
tvdpi
-
hdpi
-
xhdpi
-
xxhdpi
-
xxxhdpi
Хотя Android поддерживает предыдущие плотности, вам не нужно экспортировать растровые ресурсы в каждую плотность.
Если вы знаете, что только небольшой процент ваших пользователей имеет устройства с определенными плотностями, подумайте, нужно ли вам объединять эти плотности в вашем приложении. Если вы не включаете ресурсы для определенной плотности экрана, Android автоматически масштабирует существующие ресурсы, изначально разработанные для других плотностей экрана.
Если вашему приложению нужны только масштабированные изображения, вы можете сэкономить еще больше места, имея один вариант изображения в drawable-nodpi/
. Мы рекомендуем вам включить в ваше приложение как минимум вариант изображения xxhdpi
.
Дополнительную информацию о плотности экрана см. в разделе Размеры и плотность экрана .
Используйте рисуемые объекты
Некоторые изображения не требуют статического ресурса изображения. Вместо этого фреймворк может динамически рисовать изображение во время выполнения. Drawable
объекты (или <shape>
в XML) могут занимать небольшое количество места в вашем APK. Кроме того, Drawable
объекты XML создают монохромные изображения, соответствующие рекомендациям Material Design.
Повторное использование ресурсов
Вы можете включить отдельный ресурс для вариаций изображения, таких как тонированные, затененные или повернутые версии одного и того же изображения. Однако мы рекомендуем вам повторно использовать тот же набор ресурсов и настраивать их по мере необходимости во время выполнения.
Android предоставляет несколько утилит для изменения цвета актива, используя атрибуты android:tint
и tintMode
.
Вы также можете опустить ресурсы, которые являются только повернутым эквивалентом другого ресурса. Следующий фрагмент кода представляет собой пример превращения "большого пальца вверх" в "большой палец вниз" путем поворота в середине изображения и поворота его на 180 градусов:
<?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" />
Рендеринг из кода
Вы также можете уменьшить размер APK, процедурно отрисовав изображения. Процедурный рендеринг освобождает место, поскольку вам больше не нужно хранить файл изображения в APK.
Файлы PNG Crunch
Инструмент aapt
может оптимизировать ресурсы изображения, размещенные в res/drawable/
с помощью сжатия без потерь в процессе сборки. Например, инструмент aapt
может преобразовать PNG-файл с истинным цветом, не требующий более 256 цветов, в PNG-файл с 8-битной цветовой палитрой. Это приводит к получению изображения того же качества, но с меньшим объемом памяти.
У aapt
есть следующие ограничения:
- Инструмент
aapt
не сжимает файлы PNG, содержащиеся в папкеasset/
. - Для оптимизации инструментом
aapt
файлы изображений должны содержать не более 256 цветов. - Инструмент
aapt
может раздуть файлы PNG, которые уже сжаты. Чтобы предотвратить это, вы можете использовать флагisCrunchPngs
, чтобы отключить этот процесс для файлов PNG:
Котлин
buildTypes.all { isCrunchPngs = false }
Круто
buildTypes.all { isCrunchPngs = false }
Сжатие файлов PNG и JPEG
Вы можете уменьшить размер файла PNG без потери качества изображения, используя такие инструменты, как pngcrush , pngquant , или zopflipng . Все эти инструменты могут уменьшить размер файла PNG, сохраняя при этом воспринимаемое качество изображения.
Инструмент pngcrush
особенно эффективен. Этот инструмент перебирает фильтры PNG и параметры zlib (Deflate), используя каждую комбинацию фильтров и параметров для сжатия изображения. Затем он выбирает конфигурацию, которая дает наименьший сжатый вывод.
Для сжатия файлов JPEG можно использовать такие инструменты, как packJPG и guetzli .
Использовать формат файла WebP
Вместо файлов PNG или JPEG вы также можете использовать формат файла WebP для своих изображений. Формат WebP обеспечивает сжатие с потерями и прозрачность, как JPG и PNG, и может обеспечить лучшее сжатие, чем JPEG или PNG.
Вы можете преобразовать существующие изображения BMP, JPG, PNG или статические GIF в формат WebP с помощью Android Studio. Для получения дополнительной информации см. Создание изображений WebP .
Используйте векторную графику
Вы можете использовать векторную графику для создания иконок, не зависящих от разрешения, и других масштабируемых медиа. Вы можете использовать эту графику, чтобы значительно сократить объем вашего APK. Векторные изображения представлены в Android как объекты VectorDrawable
. С объектом VectorDrawable
файл размером 100 байт может создать четкое изображение размером с экран.
Однако системе требуется значительно больше времени для рендеринга каждого объекта VectorDrawable
, а более крупные изображения отображаются на экране еще дольше. Поэтому рассмотрите возможность использования этой векторной графики только при отображении небольших изображений.
Дополнительную информацию о работе с объектами VectorDrawable
см. в разделе Drawables .
Используйте векторную графику для анимированных изображений
Не используйте AnimationDrawable
для создания покадровой анимации, так как для этого вам придется включать отдельный файл растрового изображения для каждого кадра анимации, что значительно увеличит размер вашего APK.
Вместо этого используйте AnimatedVectorDrawableCompat
для создания анимированных векторных рисунков .
Уменьшение собственного и Java-кода
Для уменьшения размера базы кода Java и собственного кода в вашем приложении можно использовать следующие методы.
Удалить ненужный сгенерированный код
Обязательно осознайте след любого автоматически сгенерированного кода. Например, многие инструменты буферизации протоколов генерируют чрезмерное количество методов и классов, что может удвоить или утроить размер вашего приложения.
Избегайте перечислений
Один enum может добавить около 1,0–1,4 КБ к файлу classes.dex
вашего приложения. Эти дополнения могут быстро накапливаться для сложных систем или общих библиотек. Если возможно, рассмотрите возможность использования аннотации @IntDef
и сокращения кода для удаления перечислений и преобразования их в целые числа. Такое преобразование типов сохраняет все преимущества безопасности типов enum.
Уменьшить размер собственных двоичных файлов
Если ваше приложение использует собственный код и Android NDK, вы также можете уменьшить размер релизной версии вашего приложения, оптимизировав свой код. Два полезных метода — удаление отладочных символов и неизвлечение собственных библиотек.
Удалить отладочные символы
Использование отладочных символов имеет смысл, если ваше приложение находится в разработке и все еще требует отладки. Используйте инструмент arm-eabi-strip
предоставленный в Android NDK, чтобы удалить ненужные отладочные символы из собственных библиотек. После этого вы можете скомпилировать свою сборку релиза.
Избегайте извлечения собственных библиотек
При сборке релизной версии приложения упакуйте несжатые файлы .so
в APK, установив useLegacyPackaging
на false
в файле build.gradle.kts
приложения. Отключение этого флага не позволит PackageManager
копировать файлы .so
из APK в файловую систему во время установки. Этот метод делает обновления вашего приложения меньше.
Поддерживайте несколько бережливых APK
Ваш APK может содержать контент, который пользователи загружают, но никогда не используют, например, дополнительный язык или ресурсы для плотности экрана. Чтобы обеспечить минимальную загрузку для ваших пользователей, загрузите свое приложение в Google Play с помощью Android App Bundles . Загрузка пакетов приложений позволяет Google Play генерировать и обслуживать оптимизированные APK для конфигурации устройства каждого пользователя, чтобы они загружали только тот код и ресурсы, которые им нужны для запуска вашего приложения. Вам не нужно создавать, подписывать и управлять несколькими APK для поддержки разных устройств, а пользователи получают меньшие, более оптимизированные загрузки.
Если вы не публикуете свое приложение в Google Play, вы можете разделить его на несколько APK-файлов, различающихся по таким факторам, как размер экрана или поддержка текстур графическим процессором.
Когда пользователь загружает ваше приложение, его устройство получает правильный APK на основе функций и настроек устройства. Таким образом, устройства не получают ресурсы для функций, которых у них нет. Например, если у пользователя есть устройство hdpi
, ему не нужны ресурсы xxxhdpi
, которые вы можете включить для устройств с дисплеями более высокой плотности.
Для получения дополнительной информации см. разделы Создание нескольких APK и Поддержка нескольких APK .