Уменьшите размер приложения

Пользователи часто избегают загрузки приложений, которые кажутся слишком большими, особенно на развивающихся рынках, где устройства подключаются к нестабильным сетям 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 удаляет неиспользуемые ресурсы.

Для получения дополнительной информации о сокращении кода и ресурсов, а также о других способах уменьшения размера APK-файла в Android Studio см. раздел «Сокращение, обфускация и оптимизация вашего приложения» .

В Android Gradle Plugin 7.0 и более поздних версиях вы можете объявить конфигурации, которые поддерживает ваше приложение. Gradle передает эту информацию системе сборки, используя тип resourceConfigurations и параметр defaultConfig . Затем система сборки предотвращает появление ресурсов из других неподдерживаемых конфигураций в 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" encodin>g<="utf-8"?
rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_thumb_up"
    android:pivotX="50%"
    an>droid:pivotY="50%"
    android:fromDegrees="180" /

Рендеринг из кода

Вы также можете уменьшить размер APK-файла, используя процедурный рендеринг изображений. Процедурный рендеринг освобождает место, поскольку вам больше не нужно хранить файл изображения в APK-файле.

Файлы PNG с эффектом хруста

Инструмент aapt позволяет оптимизировать графические ресурсы, размещенные в res/drawable/ с помощью сжатия без потерь в процессе сборки. Например, инструмент aapt может преобразовать полноцветный PNG-файл, не требующий более 256 цветов, в 8-битный PNG-файл с цветовой палитрой. В результате получается изображение того же качества, но с меньшим объемом памяти.

Устройство aapt имеет следующие ограничения:

  • Инструмент aapt не уменьшает размер PNG-файлов, находящихся в папке asset/ .
  • Для оптимизации файлов изображений инструментом aapt необходимо использовать не более 256 цветов.
  • Инструмент aapt может искусственно увеличивать размер уже сжатых PNG-файлов. Чтобы предотвратить это, можно использовать флаг isCrunchPngs для отключения этого процесса для PNG-файлов:
  • Котлин

        buildTypes.all { isCrunchPngs = false }
        

    Классный

        buildTypes.all { isCrunchPngs = false }
        

Сжатие файлов PNG и JPEG

С помощью таких инструментов, как pngcrush , pngquant или zopflipng , можно уменьшить размер файлов PNG без потери качества изображения. Все эти инструменты позволяют уменьшить размер файлов PNG, сохраняя при этом приемлемое качество изображения.

Инструмент pngcrush особенно эффективен. Этот инструмент перебирает фильтры PNG и параметры zlib (Deflate), используя каждую комбинацию фильтров и параметров для сжатия изображения. Затем он выбирает конфигурацию, которая обеспечивает наименьший размер сжатого изображения.

Для сжатия файлов JPEG можно использовать такие инструменты, как packJPG и guetzli .

Используйте формат файла WebP.

Вместо файлов PNG или JPEG вы также можете использовать формат WebP для своих изображений. Формат WebP обеспечивает сжатие с потерями и прозрачность, как и JPG и PNG, и может обеспечить лучшее сжатие, чем JPEG или PNG.

С помощью Android Studio можно конвертировать существующие изображения в форматах BMP, JPG, PNG или статические GIF в формат WebP. Дополнительную информацию см. в разделе «Создание изображений WebP» .

Используйте векторную графику

Вы можете использовать векторную графику для создания значков и других масштабируемых медиафайлов, не зависящих от разрешения. Использование этой графики позволяет значительно уменьшить размер APK-файла. Векторные изображения в Android представлены в виде объектов VectorDrawable . С помощью объекта VectorDrawable файл размером 100 байт может создать четкое изображение размером с экран.

Однако системе требуется значительно больше времени для отрисовки каждого объекта VectorDrawable , а для отображения больших изображений требуется ещё больше времени. Поэтому рекомендуется использовать эту векторную графику только при отображении небольших изображений.

Для получения дополнительной информации о работе с объектами VectorDrawable см. раздел Drawables .

Используйте векторную графику для создания анимированных изображений.

Не используйте AnimationDrawable для создания покадровой анимации, поскольку это требует включения отдельного растрового файла для каждого кадра анимации, что значительно увеличивает размер вашего APK-файла.

Вместо этого используйте AnimatedVectorDrawableCompat для создания анимированных векторных изображений .

Сократите количество нативного и Java-кода.

Для уменьшения размера Java-кода и нативного кода в вашем приложении можно использовать следующие методы.

Удалите ненужный сгенерированный код.

Обязательно разберитесь в том, какой размер имеет любой автоматически сгенерированный код. Например, многие инструменты для работы с протоколом Protocol Buffer генерируют чрезмерное количество методов и классов, что может вдвое или втрое увеличить размер вашего приложения.

Избегайте перечислений.

Один перечисление может добавить от 1,0 до 1,4 КБ к файлу classes.dex вашего приложения. В сложных системах или с разделяемыми библиотеками эти дополнительные данные могут быстро накапливаться. По возможности, рассмотрите возможность использования аннотации @IntDef и сокращения кода для удаления перечислений и преобразования их в целые числа. Такое преобразование типов сохраняет все преимущества типобезопасности перечислений.

Уменьшить размер нативных бинарных файлов.

Если ваше приложение использует нативный код и Android NDK, вы также можете уменьшить размер релизной версии приложения, оптимизировав код. Два полезных метода — это удаление отладочных символов и отказ от извлечения нативных библиотек.

Удалить отладочные символы

Использование отладочных символов имеет смысл, если ваше приложение находится в разработке и все еще требует отладки. Используйте инструмент arm-eabi-strip входящий в состав Android NDK, чтобы удалить ненужные отладочные символы из нативных библиотек. После этого вы можете скомпилировать свою релизную сборку.

Избегайте извлечения собственных библиотек.

При сборке релизной версии вашего приложения упакуйте несжатые файлы .so в APK, установив параметр useLegacyPackaging в значение false в файле build.gradle.kts вашего приложения. Отключение этого флага предотвратит копирование файлов .so из APK в файловую систему во время установки PackageManager . Этот метод позволяет уменьшить размер обновлений вашего приложения.

Поддерживайте несколько оптимизированных APK-файлов.

Ваш APK-файл может содержать контент, который пользователи загружают, но никогда не используют, например, дополнительные языковые модули или ресурсы, зависящие от плотности экрана. Чтобы обеспечить минимальный размер загружаемого файла для ваших пользователей, загрузите свое приложение в Google Play с помощью Android App Bundles . Загрузка пакетов приложений позволяет Google Play генерировать и предоставлять оптимизированные APK-файлы для конфигурации устройства каждого пользователя, так что они загружают только тот код и ресурсы, которые необходимы для работы вашего приложения. Вам не нужно создавать, подписывать и управлять несколькими APK-файлами для поддержки разных устройств, а пользователи получают меньшие по размеру и более оптимизированные файлы для загрузки.

Если вы не публикуете свое приложение в Google Play, вы можете разделить его на несколько APK-файлов, различающихся такими факторами, как размер экрана или поддержка текстур графического процессора.

Когда пользователь загружает ваше приложение, его устройство получает правильный APK-файл, соответствующий функциям и настройкам устройства. Таким образом, устройства не получают ресурсы для функций, которых у них нет. Например, если у пользователя устройство hdpi , ему не нужны ресурсы xxxhdpi , которые вы могли бы включить для устройств с дисплеями более высокой плотности.

Для получения дополнительной информации см. разделы «Создание нескольких APK-файлов» и «Поддержка нескольких APK-файлов» .