Привет, Хабр! Сегодня расскажу, что такое Android App Bundles, как их использовать в реальном проекте и на сколько нам удалось уменьшить размер приложения, не прикладывая очень больших усилий.
Вступление. Что такое Android App Bundles?
Начиная с августа 2021 года Google ввел правило - новые приложения должны публиковаться с Android App Bundles. По своей сути, Android App Bundle - это формат публикации, который включает в себя весь скомпилированный код и ресурсы вашего приложения, а также откладывает создание APK и подписание его в Google Play.
Google Play использует ваш app bundle для создания и обслуживания оптимизированных APK-файлов для каждой конфигурации устройства, поэтому для запуска вашего приложения загружаются только код и ресурсы, необходимые для конкретного устройства. Вам больше не нужно создавать, подписывать и управлять несколькими APK-файлами, чтобы оптимизировать поддержку различных устройств, а пользователи получают более оптимизированные загрузки.
Ограничения Android App Bundles
Публикация с помощью наборов Android App Bundle помогает пользователям устанавливать ваше приложение с минимально возможным количеством загрузок и увеличивает предельный размер сжатой загрузки до 150 МБ . То есть, когда пользователь загружает ваше приложение, общий размер сжатых APK-файлов, необходимых для установки вашего приложения (например, базовый APK + APK-файлы конфигурации), не должен превышать 150 МБ. Любые последующие загрузки, такие как загрузка on demand feature module(и его конфигурационных APK-файлов), также должны соответствовать этому ограничению размера загрузки. Assets-пакеты не влияют на это ограничение по размеру, но имеют другие ограничения по размеру.
Если при загрузке пакета приложений Play Console обнаружит, что размер любой из возможных загрузок вашего приложения или его on demand feature превышает 150 МБ, вы получите сообщение об ошибке.
Подготовка проекта к миграции
Прежде чем переходить к имплементации в проекте, пройдемся по основным этапам подготовки.
Используйте shrinking, обфускацию и оптимизацию вашего проекта, это позволит сократить размер приложения путем удаления неиспользуемого кода и ресурсов. Детальнее можно почитать в официальных гайдах.
Следуйте лучшим практикам, чтобы еще больше уменьшить размер приложения(использование drawable objects, использование WebP вместо jpg и png, и т.д.). Больше тут.
Рассмотрите возможность преобразования некоторого функционала, который используется только некоторыми из ваших пользователей, в dynamic feature modules, которые ваше приложение может загрузить позже по запросу. Имейте в виду, что для этого может потребоваться некоторый рефакторинг вашего приложения, поэтому сначала попробуйте другие предложения, описанные выше.
Используйте разделение ресурсов по папкам(drawables):
для векторной графики(svg) используйте папку drawable-nodpi, Система не масштабирует эти ресурсы независимо от плотности текущего экрана;
растровую графику распределяйте по папкам drawable-*dpi, для App Bundles не будет загружаться графика, не соответствующая размеру экрана.
Настройка базового модуля
App Bundle отличается от APK тем, что вы не можете развернуть его на устройстве. Это формат для публикации, который включает весь скомпилированный код и ресурсы вашего приложения в один артефакт сборки. После того, как вы загрузите App Bundle, подписанный релизным ключем, Google Play будет иметь все необходимое для создания и подписания APK-файлов вашего приложения и предоставления их пользователям.
Большинство проектов приложений не потребуют больших усилий для поддержки пакетов Android App Bundle. Это потому, что модуль, который включает код и ресурсы для базового APK вашего приложения, является стандартным модулем приложения, который вы получаете по умолчанию при создании нового проекта приложения в Android Studio. Модуль, к которому применяется application
plugin ниже к своему build.gradle
файлу, предоставляет код и ресурсы для основных функций вашего приложения.
plugins {
// The standard application plugin creates your app's base module.
id("com.android.application")
}
Помимо предоставления основных функций для вашего приложения, базовый модуль также предоставляет множество конфигураций сборки и записей манифеста, которые влияют на весь проект вашего приложения.
Для большинства существующих проектов приложений вам не нужно ничего менять в конфигурации сборки вашего базового модуля. Однако, если вы планируете добавить feature modules в свой проект приложения или если вы ранее выпустили свое приложение с использованием нескольких APK, вам следует помнить о некоторых аспектах конфигурации сборки базового модуля. Вот так выглядит схема модулей при использовании App Bundles:
Код версии и обновления приложений
С пакетами Android App Bundle вам больше не нужно управлять кодами версий для нескольких APK, которые вы загружаете в Google Play. Вместо этого вы управляете только одним кодом версии в базовом модуле вашего приложения, как показано ниже:
// In your base module build.gradle file
android {
defaultConfig {
…
// You specify your app’s version code only in the base module.
versionCode 5
versionName "1.0"
}
}
После загрузки пакета приложений Google Play использует код версии в вашем базовом модуле, чтобы назначить один и тот же код версии всем APK, которые он генерирует из этого пакета. То есть, когда устройство загружает и устанавливает ваше приложение, все разделенные APK для этого приложения имеют один и тот же код версии.
Если вы хотите обновить свое приложение новым кодом или ресурсами, вы должны обновить код версии в базовом модуле вашего приложения и создать новый полный комплект приложения. Когда вы загружаете этот набор приложений в Google Play, он создает новый набор APK на основе кода версии, указанного в базовом модуле. Впоследствии, когда пользователи обновят ваше приложение, Google Play предоставит им обновленные версии всех APK, установленных в настоящее время на устройстве. То есть все установленные APK обновляются до кода новой версии.
Также стоит обратить внимание на следующие нюансы:
Релизная подпись приложения. Если вы включаете информацию о подписи в свои файлы сборки, вы должны включать ее только в файл конфигурации сборки базового модуля. Дополнительные сведения см. в разделе Настройка Gradle для подписи приложения.
Code shrinking. Если вы хотите включить сжатие кода для всего проекта приложения (включая его функциональные модули), вы должны сделать это из файла build.gradle базового модуля. То есть вы можете включить пользовательские правила ProGuard в feature module, но
minifyEnabled
свойство в конфигурациях сборки feature module игнорируется.Блок
splits
игнорируется. При компиляции App Bundle, Gradle игнорирует свойства вandroid.splits
блоке. Если вы хотите контролировать, какие типы APK-файлов конфигурации поддерживает ваш app bundle, вместо этого используйтеandroid.bundle.
Управление версиями приложения. Базовый модуль определяет version code и version name для всего проекта приложения. Для получения дополнительной информации перейдите в раздел о том, как управлять обновлениями приложений .
Итак, перейдем собственно к настройке gradle-файла вашего базового модуля:
android {
// When building Android App Bundles, the splits block is ignored.
// You can remove it, unless you're going to continue to build multiple
// APKs in parallel with the app bundle
splits {...}
// Instead, use the bundle block to control which types of configuration APKs
// you want your app bundle to support.
bundle {
language {
// This property is set to true by default.
// You can specify `false` to turn off
// generating configuration APKs for language resources.
// These resources are instead packaged with each base and
// feature APK.
// Continue reading below to learn about situations when an app
// might change setting to `false`, otherwise consider leaving
// the default on for more optimized downloads.
enableSplit = false
}
density {
// This property is set to true by default.
enableSplit = true
}
abi {
// This property is set to true by default.
enableSplit = true
}
}
}
Основное внимание стоит обратить на блок bundle - это и есть настройка наших Android App Bundles.
Блок language.
Google Play определяет, какие языковые ресурсы устанавливать вместе с приложением, на основе выбора языка в настройках устройства пользователя. Представьте пользователя, который меняет свой системный язык по умолчанию после того, как уже загрузил ваше приложение. Если ваше приложение поддерживает этот язык, устройство запрашивает и загружает дополнительные APK-файлы конфигурации для этих языковых ресурсов из Google Play.
Для приложений, которые предлагают средство выбора языка внутри приложения и динамически изменяют язык приложения, независимо от языковых настроек системного уровня, необходимо внести некоторые изменения, чтобы предотвратить сбои из-за отсутствия ресурсов. Задайте для android.bundle.language.enableSplit
свойства значение false
или рассмотрите возможность реализации языковой загрузки по запросу с использованием библиотеки Play Core.
Другими словами, если у вас поддержка нескольких языков и есть возможность менять язык внутри приложения, вам необходимо для блока language задать enableSplit = false и реализовать подгрузку нужных языков, как описано в разделе Download additional language resources.
Блок destiny.
Этот блок отвечает за подгрузку графики только для нужной плотности экрана(то что мы делали на этапе подготовки к миграции, раскладывали ресурсы по попкам drawable-*dpi).
Параметр enableSplit отвечает за загрузку графики. Если выставить enableSplit = true, будет загружена графика только для текущей плотности экрана.
Блок abi.
В разных устройствах Android используются разные процессоры, которые, в свою очередь, поддерживают разные наборы инструкций. Каждая комбинация ЦП и набора команд имеет собственный Application Binary Interface(ABI).
Параметр enableSplit отвечает за загрузку ABI. Если выставить enableSplit = true, будет загружен набор инструкций только для текущего процессора.
Итог
В качестве итога скажу, что более 1 миллиона приложений и игр используют пакеты приложений для публикации своих производственных выпусков в Google Play, включая большинство популярных приложений, что составляет миллиарды активных установок. Если вы используете Google Play для установки приложений, многие приложения на вашем устройстве были опубликованы в виде App Bundles.
В нашем же случае, мы значительно смогли уменьшить размер нашего приложения. Размер при скачивании уменьшился с 44.22МБ до 27.61МБ(может варьироваться в зависимости от модели устройства, данные для Samsung S21):
Размер чистой только что установленной версии уменьшился с 117МБ до 72.52МБ (может варьироваться в зависимости от модели устройства, данные для Samsung S21):
Спасибо за внимание! Делитесь в комментариях, на сколько вам удалось уменьшить размер приложения =)