Система сборки Android компилирует ресурсы и исходный код приложения и упаковывает их в APK-файлы или наборы Android App Bundle, которые можно тестировать, развертывать, подписывать и распространять.
В статьях Обзор сборки Gradle и Структура сборки Android мы обсудили концепции сборки и структуру приложения Android. Теперь пришло время настроить сборку.
Глоссарий по сборкам Android
Gradle и плагин Android Gradle позволяют настраивать следующие аспекты сборки:
- Типы сборки
-
Типы сборки определяют некоторые свойства, которые Gradle использует при сборке и упаковке приложения. Обычно типы сборки настраиваются для разных этапов жизненного цикла разработки.
Например, отладочная сборка позволяет использовать параметры отладки и подписывать приложение ключом отладки, а конечная сборка может сжимать и обфусцировать приложение, а также подписывать его ключом выпуска для распространения.
Чтобы создать приложение, необходимо определить хотя бы один тип сборки. По умолчанию Android Studio создает типы сборки debug и release. Чтобы начать настройку параметров упаковки для приложения, узнайте, как настроить типы сборки.
- Версии продукта
- Версии продукта – это разные версии приложения, которые вы можете выпускать для пользователей, например бесплатная и платная. Вы можете настроить версии продукта так, чтобы в них использовались разные коды и ресурсы, а также общие для всех версий приложения части. Версии продукта необязательны, и их нужно создавать вручную. Чтобы начать создавать разные версии приложения, узнайте, как настроить версии продукта.
- Варианты сборки
- Вариант сборки – это декартово произведение типа сборки и версии продукта, а также конфигурация, которую Gradle использует для сборки приложения. С помощью вариантов сборки вы можете создавать отладочные версии продуктов во время разработки и подписанные конечные версии для распространения. Хотя вы не настраиваете варианты сборки напрямую, вы настраиваете типы сборки и версии продукта, которые их формируют. При создании дополнительных типов сборки или версий продукта также создаются дополнительные варианты сборки. Подробнее о том, как создавать варианты сборки и управлять ими…
- Записи манифеста
- Вы можете указать значения для некоторых свойств файла манифеста в конфигурации варианта сборки. Эти значения переопределяют существующие значения в файле манифеста. Это удобно, если вы хотите создать несколько вариантов приложения с разными названиями, минимальными или целевыми версиями SDK. Если файлов манифеста несколько, инструмент объединения объединяет их настройки.
- Зависимости
- Система сборки управляет зависимостями проекта из локальной файловой системы и из удаленных репозиториев. Это означает, что вам не нужно вручную искать, скачивать и копировать двоичные пакеты зависимостей в каталог проекта. Подробнее о том, как добавить зависимости сборки…
- Подписание
- Система сборки позволяет указать настройки подписи в конфигурации сборки и может автоматически подписывать приложение в процессе сборки. Система сборки подписывает отладочную версию ключом и сертификатом по умолчанию, используя известные учетные данные, чтобы избежать запроса пароля во время сборки. Система сборки не подписывает конечную версию, если вы не задали конфигурацию подписи для этой сборки. Если у вас нет ключа выпуска, вы можете сгенерировать его, как описано в разделе Подписание приложения. Подписанные конечные сборки необходимы для распространения приложений через большинство магазинов приложений.
- Удаление неиспользуемого кода и ресурсов
- Система сборки позволяет указать отдельный файл правил ProGuard для каждого варианта сборки. При создании приложения система сборки применяет соответствующий набор правил, чтобы уменьшить размер кода и ресурсов с помощью встроенных инструментов, таких как R8. Чтобы уменьшить размер APK-файла или набора App Bundle, сократите код и ресурсы.
- Поддержка нескольких APK-файлов
- Система сборки позволяет автоматически создавать разные APK-файлы, каждый из которых содержит только код и ресурсы, необходимые для определенной плотности экрана или двоичного интерфейса приложений (ABI). Подробнее о том, как создать несколько APK-файлов… Однако мы рекомендуем выпускать один набор AAB, поскольку он позволяет разделять ресурсы не только по плотности пикселей и ABI, но и по языку. Кроме того, вам не придется загружать в Google Play несколько объектов. Все новые приложения, отправленные после августа 2021 года, должны использовать AAB.
Версии Java в сборках Android
Независимо от того, написан ли ваш исходный код на Java, Kotlin или на обоих языках, есть несколько мест, где вы должны выбрать версию JDK или языка Java для своей сборки. Подробную информацию можно найти в статье Версии Java в сборках Android.
Файлы конфигурации сборки
Чтобы создать собственную конфигурацию сборки, необходимо внести изменения в один или несколько файлов конфигурации сборки. В этих файлах обычного текста используется предметно-ориентированный язык (DSL) для описания логики сборки и управления ею с помощью скрипта Kotlin, который является вариантом языка Kotlin. Для настройки сборок также можно использовать Groovy – динамический язык для виртуальной машины Java (JVM).
Чтобы настроить сборку, не нужно знать Kotlin или Groovy, поскольку плагин Android Gradle содержит большинство необходимых элементов DSL. Подробные сведения о DSL плагина Android Gradle можно найти в справочной документации по DSL. Скрипт Kotlin также зависит от базового Gradle Kotlin DSL.
При создании нового проекта Android Studio автоматически создает некоторые из этих файлов и заполняет их значениями по умолчанию. Обзор созданных файлов приведен в разделе Структура сборки Android.
Файл Gradle Wrapper
Оболочка Gradle (gradlew) – это небольшое приложение, включенное в исходный код, которое скачивает и запускает Gradle.
Это обеспечивает более стабильное выполнение сборки. Разработчики скачивают исходный код приложения и запускают gradlew. Будет скачан необходимый дистрибутив Gradle, а затем запустится сборка приложения.
Файл gradle/wrapper/gradle-wrapper.properties содержит свойство distributionUrl, которое описывает, какая версия Gradle используется для запуска сборки.
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Файл настроек Gradle
Файл settings.gradle.kts (для Kotlin DSL) или settings.gradle (для Groovy DSL) находится в корневом каталоге проекта. В этом файле определяются настройки хранилища на уровне проекта и указывается, какие модули Gradle должен включить при сборке приложения. В многомодульных проектах необходимо указать каждый модуль, который должен войти в окончательную сборку.
Для большинства проектов файл по умолчанию выглядит следующим образом:
Kotlin
pluginManagement { /** * The pluginManagement.repositories block configures the * repositories Gradle uses to search or download the Gradle plugins and * their transitive dependencies. Gradle pre-configures support for remote * repositories such as JCenter, Maven Central, and Ivy. You can also use * local repositories or define your own remote repositories. Here we * define the Gradle Plugin Portal, Google's Maven repository, * and the Maven Central Repository as the repositories Gradle should use to look for its * dependencies. */ repositories { gradlePluginPortal() google() mavenCentral() } } dependencyResolutionManagement { /** * The dependencyResolutionManagement.repositories * block is where you configure the repositories and dependencies used by * all modules in your project, such as libraries that you are using to * create your application. However, you should configure module-specific * dependencies in each module-level build.gradle file. For new projects, * Android Studio includes Google's Maven repository and the Maven Central * Repository by default, but it does not configure any dependencies (unless * you select a template that requires some). */ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } } rootProject.name = "My Application" include(":app")
Яркий
pluginManagement { /** * The pluginManagement.repositories block configures the * repositories Gradle uses to search or download the Gradle plugins and * their transitive dependencies. Gradle pre-configures support for remote * repositories such as JCenter, Maven Central, and Ivy. You can also use * local repositories or define your own remote repositories. Here we * define the Gradle Plugin Portal, Google's Maven repository, * and the Maven Central Repository as the repositories Gradle should use to look for its * dependencies. */ repositories { gradlePluginPortal() google() mavenCentral() } } dependencyResolutionManagement { /** * The dependencyResolutionManagement.repositories * block is where you configure the repositories and dependencies used by * all modules in your project, such as libraries that you are using to * create your application. However, you should configure module-specific * dependencies in each module-level build.gradle file. For new projects, * Android Studio includes Google's Maven repository and the Maven Central * Repository by default, but it does not configure any dependencies (unless * you select a template that requires some). */ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } } rootProject.name = "My Application" include ':app'
Файл сборки верхнего уровня
Файл build.gradle.kts (для Kotlin DSL) или build.gradle (для Groovy DSL) верхнего уровня находится в корневом каталоге проекта. Обычно в нем определяются общие версии плагинов, используемых модулями в проекте.
В следующем примере кода показаны настройки по умолчанию и элементы DSL в скрипте сборки верхнего уровня после создания нового проекта:
Kotlin
plugins { /** * Use `apply false` in the top-level build.gradle file to add a Gradle * plugin as a build dependency but not apply it to the current (root) * project. Don't use `apply false` in sub-projects. For more information, * see Applying external plugins with same version to subprojects. */ id("com.android.application") version "9.4.0" apply false id("com.android.library") version "9.4.0" apply false id("org.jetbrains.kotlin.android") version "2.4.10" apply false }
Яркий
plugins { /** * Use `apply false` in the top-level build.gradle file to add a Gradle * plugin as a build dependency but not apply it to the current (root) * project. Don't use `apply false` in sub-projects. For more information, * see Applying external plugins with same version to subprojects. */ id 'com.android.application' version '9.4.0' apply false id 'com.android.library' version '9.4.0' apply false id 'org.jetbrains.kotlin.android' version '2.4.10' apply false }
Файл сборки на уровне модуля
Файл build.gradle.kts (для Kotlin DSL) или build.gradle (для Groovy DSL) на уровне модуля находится в каждом каталоге project/module/. Он позволяет настраивать параметры сборки для конкретного модуля, в котором он находится. Настроив эти параметры сборки, вы сможете задать собственные параметры упаковки, например дополнительные типы сборки и версии продукта, а также переопределить настройки в манифесте приложения main/ или скрипте сборки верхнего уровня.
Настройки Android SDK
Файл сборки на уровне модуля для вашего приложения содержит настройки, которые указывают версии Android SDK, используемые при компиляции, выборе поведения платформы и указании минимальной версии, на которой работает ваше приложение.
-
compileSdk -
compileSdkопределяет, какие API Android и Java доступны при компиляции исходного кода. Чтобы использовать новейшие функции Android, при компиляции используйте последнюю версию Android SDK.Некоторые API платформы Android могут быть недоступны в более ранних уровнях API. Вы можете условно защитить использование новых функций или использовать библиотеки совместимости AndroidX, чтобы использовать новые функции с более низкими уровнями API Android.
Каждый Android SDK предоставляет подмножество Java API для использования в приложении. В таблице Какие Java API можно использовать в исходном коде Java или Kotlin показано, какой уровень Java API доступен в зависимости от версии Android SDK. Новые Java API поддерживаются в более ранних версиях Android благодаря десахаризации, которую необходимо включить в сборке.
Если вам нужно выполнить компиляцию для определенного дополнительного уровня API, используйте расширенный синтаксис блока
compileSdkи укажитеminorApiLevel:Kotlin
android { compileSdk { version = release(36) { minorApiLevel = 1 } } }
Яркий
android { compileSdk { version = release(36) { minorApiLevel = 1 } } }
Android Studio показывает предупреждения, если
compileSdkконфликтует с текущей версией Android Studio, AGP или требованиями к зависимостям библиотек проекта. -
minSdk -
minSdkуказывает самую раннюю версию Android, которую должно поддерживать ваше приложение. НастройкаminSdkограничивает список устройств, на которые можно установить приложение.Для поддержки более ранних версий Android может потребоваться больше условных проверок в коде или более частое использование библиотек совместимости AndroidX. Вам следует сопоставить затраты на поддержку более ранних версий с процентом пользователей, которые все ещё используют эти версии. Текущие проценты использования версий можно посмотреть на диаграмме в мастере создания проектов Android Studio.
При редактировании кода в Android Studio или выполнении проверок во время сборки lint будет предупреждать об использовании API, недоступных в
minSdk. Чтобы исправить эти ошибки, сделайте новые функции условными или используйтеAppcompatдля обратной совместимости. -
targetSdk -
targetSdkслужит двум целям:- Она определяет поведение приложения во время выполнения.
- Она подтверждает, какую версию Android вы тестировали.
Если на устройстве установлена более поздняя версия Android, чем указано в параметре
targetSdk, приложение будет запущено в режиме совместимости, который работает так же, как более ранняя версия, указанная в параметреtargetSdk. Например, когда в API 23 была представлена модель разрешений, не все приложения были готовы сразу перейти на нее. Если задать дляtargetSdkзначение 22, эти приложения смогут работать на устройствах с API 23 без использования динамических разрешений и использовать функции, включенные в последнюю версиюcompileSdk. Правила распространения Google Play предусматривают дополнительные требования к целевому уровню API.Значение
targetSdkне связано со значениемcompileSdk. Например, значениеtargetSdkможет быть выше, ниже или равно значениюcompileSdk.
Примечание. Значения compileSdk и targetSdk могут не совпадать. Помните о следующих основных принципах:
compileSdkдает доступ к новым APItargetSdkзадает поведение приложения во время выполнения.
Пример скрипта сборки модуля приложения
В этом примере скрипта сборки модуля приложения для Android показаны некоторые основные элементы и настройки DSL:
Kotlin
/** * The first section in the build configuration applies the Android Gradle plugin * to this build and makes the android block available to specify * Android-specific build options. */ plugins { id("com.android.application") } /** * Locate (and possibly download) a JDK used to build your kotlin * source code. This also acts as a default for sourceCompatibility, * targetCompatibility and jvmTarget. Note that this does not affect which JDK * is used to run the Gradle build itself, and does not need to take into * account the JDK version required by Gradle plugins (such as the * Android Gradle Plugin) */ kotlin { jvmToolchain(11) } /** * The android block is where you configure all your Android-specific * build options. */ android { /** * The app's namespace. Used primarily to access app resources. */ namespace = "com.example.myapp" /** * compileSdk specifies the Android API level Gradle should use to * compile your app. This means your app can use the API features included in * this API level and lower. */ compileSdk = 36 /** * The defaultConfig block encapsulates default settings and entries for all * build variants and can override some attributes in main/AndroidManifest.xml * dynamically from the build system. You can configure product flavors to override * these values for different versions of your app. */ defaultConfig { // Uniquely identifies the package for publishing. applicationId = "com.example.myapp" // Defines the minimum API level required to run the app. minSdk = 23 // Specifies the API level used to test the app. targetSdk = 36 // Defines the version number of your app. versionCode = 1 // Defines a user-friendly version name for your app. versionName = "1.0" } /** * The buildTypes block is where you can configure multiple build types. * By default, the build system defines two build types: debug and release. The * debug build type is not explicitly shown in the default build configuration, * but it includes debugging tools and is signed with the debug key. The release * build type applies ProGuard settings and is not signed by default. */ buildTypes { /** * By default, Android Studio configures the release build type to enable code * shrinking, using minifyEnabled, and specifies the default ProGuard rules file. */ getByName("release") { isMinifyEnabled = true // Enables code shrinking for the release build type. proguardFiles( getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" ) } } /** * The productFlavors block is where you can configure multiple product flavors. * This lets you create different versions of your app that can * override the defaultConfig block with their own settings. Product flavors * are optional, and the build system does not create them by default. * * This example creates a free and paid product flavor. Each product flavor * then specifies its own application ID, so that they can exist on the Google * Play Store or an Android device simultaneously. * * If you declare product flavors, you must also declare flavor dimensions * and assign each flavor to a flavor dimension. */ flavorDimensions += "tier" productFlavors { create("free") { dimension = "tier" applicationId = "com.example.myapp.free" } create("paid") { dimension = "tier" applicationId = "com.example.myapp.paid" } } /** * To override source and target compatibility (if different from the * toolchain JDK version), add the following. All of these * default to the same value as kotlin.jvmToolchain. If you're using the * same version for these values and kotlin.jvmToolchain, you can * remove these blocks. */ //compileOptions { // sourceCompatibility = JavaVersion.VERSION_11 // targetCompatibility = JavaVersion.VERSION_11 //} //kotlinOptions { // jvmTarget = "11" //} } /** * The dependencies block in the module-level build configuration file * specifies dependencies required to build only the module itself. * To learn more, go to Add build dependencies. */ dependencies { implementation(project(":lib")) implementation("androidx.appcompat:appcompat:1.8.0") implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) }
Яркий
/** * The first line in the build configuration applies the Android Gradle plugin * to this build and makes the android block available to specify * Android-specific build options. */ plugins { id 'com.android.application' } /** * Locate (and possibly download) a JDK used to build your kotlin * source code. This also acts as a default for sourceCompatibility, * targetCompatibility and jvmTarget. Note that this does not affect which JDK * is used to run the Gradle build itself, and does not need to take into * account the JDK version required by Gradle plugins (such as the * Android Gradle Plugin) */ kotlin { jvmToolchain 11 } /** * The android block is where you configure all your Android-specific * build options. */ android { /** * The app's namespace. Used primarily to access app resources. */ namespace 'com.example.myapp' /** * compileSdk specifies the Android API level Gradle should use to * compile your app. This means your app can use the API features included in * this API level and lower. */ compileSdk 36 /** * The defaultConfig block encapsulates default settings and entries for all * build variants and can override some attributes in main/AndroidManifest.xml * dynamically from the build system. You can configure product flavors to override * these values for different versions of your app. */ defaultConfig { // Uniquely identifies the package for publishing. applicationId 'com.example.myapp' // Defines the minimum API level required to run the app. minSdk 23 // Specifies the API level used to test the app. targetSdk 36 // Defines the version number of your app. versionCode 1 // Defines a user-friendly version name for your app. versionName "1.0" } /** * The buildTypes block is where you can configure multiple build types. * By default, the build system defines two build types: debug and release. The * debug build type is not explicitly shown in the default build configuration, * but it includes debugging tools and is signed with the debug key. The release * build type applies ProGuard settings and is not signed by default. */ buildTypes { /** * By default, Android Studio configures the release build type to enable code * shrinking, using minifyEnabled, and specifies the default ProGuard rules file. */ release { minifyEnabled true // Enables code shrinking for the release build type. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } /** * The productFlavors block is where you can configure multiple product flavors. * This lets you create different versions of your app that can * override the defaultConfig block with their own settings. Product flavors * are optional, and the build system does not create them by default. * * This example creates a free and paid product flavor. Each product flavor * then specifies its own application ID, so that they can exist on the Google * Play Store or an Android device simultaneously. * * If you declare product flavors, you must also declare flavor dimensions * and assign each flavor to a flavor dimension. */ flavorDimensions "tier" productFlavors { free { dimension "tier" applicationId 'com.example.myapp.free' } paid { dimension "tier" applicationId 'com.example.myapp.paid' } } /** * To override source and target compatibility (if different from the * tool chain JDK version), add the following. All of these * default to the same value as kotlin.jvmToolchain. If you're using the * same version for these values and kotlin.jvmToolchain, you can * remove these blocks. */ //compileOptions { // sourceCompatibility JavaVersion.VERSION_11 // targetCompatibility JavaVersion.VERSION_11 //} //kotlinOptions { // jvmTarget = '11' //} } /** * The dependencies block in the module-level build configuration file * specifies dependencies required to build only the module itself. * To learn more, go to Add build dependencies. */ dependencies { implementation project(":lib") implementation 'androidx.appcompat:appcompat:1.8.0' implementation fileTree(dir: 'libs', include: ['*.jar']) }
Файлы свойств Gradle
В Gradle также есть два файла свойств, расположенных в корневом каталоге проекта. С их помощью можно задавать настройки для самого набора инструментов сборки Gradle.
-
gradle.properties - Здесь можно задать настройки Gradle для всего проекта, например максимальный размер кучи для демона Gradle. Подробнее о среде сборки…
-
local.properties -
Настраивает свойства локальной среды для системы сборки, включая следующие:
ndk.dir– путь к NDK. Это свойство больше не поддерживается. Все скачанные версии NDK устанавливаются в каталогndk, который находится в каталоге Android SDK.sdk.dir– путь к Android SDK.cmake.dir– путь к CMake.ndk.symlinkdir– в Android Studio 3.5 и более поздних версиях создает символическую ссылку на NDK, которая может быть короче, чем путь к установленному NDK.
Переназначьте NDK на более короткий путь (только для Windows)
В Windows инструменты в установленной папке NDK, например ld.exe, имеют длинные пути. Инструменты не поддерживают длинные пути.
Чтобы сократить путь, в файле local.properties задайте свойство ndk.symlinkdir. Это позволит плагину Android Gradle создать символическую ссылку на NDK. Путь к символической ссылке может быть короче, чем к существующей папке NDK.
Например, ndk.symlinkdir = C:\ приводит к следующей символической ссылке:
C:\ndk\19.0.5232133
Синхронизировать проект с файлами Gradle
Когда вы вносите изменения в файлы конфигурации сборки в проекте, Android Studio требует синхронизировать файлы проекта, чтобы импортировать изменения конфигурации сборки и выполнить некоторые проверки, чтобы убедиться, что конфигурация не создает ошибок сборки.
Чтобы синхронизировать файлы проекта, нажмите Sync Now (Синхронизировать) на панели уведомлений, которая появляется при внесении изменений (см. рис. 2), или выберите Sync Project (Синхронизировать проект)
в строке меню. Если Android Studio обнаружит ошибки в конфигурации (например, в исходном коде используются функции API, доступные только на уровне API выше, чем compileSdkVersion), в окне Messages (Сообщения) появится описание проблемы.
Наборы исходных файлов
Android Studio логически группирует исходный код и ресурсы для каждого модуля в наборы исходных файлов. При создании нового модуля Android Studio создает в нем набор исходных файлов main/. Набор исходных файлов main/ модуля включает код и ресурсы, используемые всеми его вариантами сборки.
Дополнительные каталоги наборов исходных файлов необязательны, и Android Studio не создает их автоматически при настройке новых вариантов сборки. Однако создание наборов исходных файлов, таких как main/, помогает упорядочить файлы и ресурсы, которые Gradle должен использовать только при сборке определенных версий приложения.
-
src/main/ - Этот набор исходных файлов включает код и ресурсы, общие для всех вариантов сборки.
-
src/buildType/ - Создайте этот набор исходных файлов, чтобы включить код и ресурсы только для определенного типа сборки.
-
src/productFlavor/ -
Создайте этот набор исходных файлов, чтобы включить код и ресурсы только для определенной версии продукта.
Примечание. Если вы настроите сборку так, чтобы объединить несколько версий продукта, то сможете создать каталоги наборов исходных файлов для каждой комбинации версий продукта между группами вариантов:
src/productFlavor1ProductFlavor2/. -
src/productFlavorBuildType/ - Создайте этот набор исходных файлов, чтобы включить код и ресурсы только для определенного варианта сборки.
Например, чтобы создать версию fullDebug, система сборки объединяет код, настройки и ресурсы из следующих наборов исходных файлов:
-
src/fullDebug/(набор исходных файлов варианта сборки) -
src/debug/(набор исходных файлов для типа сборки) -
src/full/(набор исходных файлов для версии продукта) -
src/main/(основной набор исходных файлов)
Примечание. Чтобы создать файл или каталог в Android Studio, выберите File (Файл) > New (Создать) и укажите нужный набор исходных файлов. Доступные наборы исходных файлов зависят от конфигураций сборки. Android Studio автоматически создает необходимые каталоги, если они ещё не существуют.
Если разные наборы исходных файлов содержат разные версии одного и того же файла, Gradle выбирает файл, используя следующий порядок приоритета. Наборы исходных файлов слева переопределяют файлы и настройки наборов исходных файлов справа:
вариант сборки > тип сборки > версия продукта > основной набор исходных файлов > зависимости библиотеки
Это позволяет Gradle использовать файлы, относящиеся к конкретному варианту сборки, и повторно использовать действия, логику приложения и ресурсы, общие для других версий приложения.
При объединении нескольких манифестов Gradle использует тот же порядок приоритета, поэтому каждый вариант сборки может определять разные компоненты или разрешения в конечном манифесте. Подробнее о том, как создавать наборы исходных файлов…
Каталоги версий
Если в вашей сборке несколько модулей с общими зависимостями или у вас несколько независимых проектов с общими зависимостями, рекомендуем использовать каталог версий или спецификацию материалов (BOM), чтобы указать общие версии.
Другие системы сборки
Создание приложений для Android с помощью Bazel возможно, но официально не поддерживается. Android Studio официально не поддерживает проекты Bazel.
Чтобы лучше понять текущие ограничения сборки с помощью Bazel, ознакомьтесь с известными проблемами.