Перейти к содержимому

Инструкции по настройке · Kotlin / Jetpack Compose

Закрытое тестирование Google Play для приложений на Kotlin и Jetpack Compose

Для нативных Android-проектов в Android Studio: соберите подписанный релизный бандл в IDE или через Gradle, настройте закрытый трек и удержите 12 тестировщиков 14 дней, не получив ошибок, которые проявляются только в release из-за R8 и новых уровней API.

Сборка
./gradlew bundleRelease
Код версии
defaultConfig → versionCode
Целевой API
targetSdk = 36

Соберите подписанный релизный бандл

  1. Задайте ID приложения

    В app/build.gradle.kts значение applicationId в defaultConfig определяет приложение в Google Play и не может измениться после первой загрузки. namespace относится только к коду и может отличаться.

  2. Соберите в Android Studio

    Выберите Build → Generate Signed Bundle/APK, затем Android App Bundle, укажите хранилище и ключ (или Create new), вариант сборки release и нажмите Create.

  3. Или из командной строки

    Когда подпись настроена в Gradle (следующий раздел), выполните задачу ниже. Бандл сохраняется в app/build/outputs/bundle/release/.

Terminal
./gradlew bundleRelease

Перед загрузкой установите вариант release на устройство. Ошибки из-за R8 или настроек, действующих только в release, при запуске debug не проявляются:

Terminal
./gradlew installRelease

Ключ загрузки и подписание приложений в Google Play

Новые приложения обязаны использовать подписание в Google Play: ключ подписи приложения хранит Google, а каждую загрузку вы подписываете ключом загрузки. Мастер Android Studio умеет создавать хранилище ключей и рекомендует срок действия не меньше 25 лет.

Чтобы подписывать из командной строки или в CI, храните учётные данные в файле keystore.properties вне системы контроля версий и читайте его в app/build.gradle.kts:

keystore.properties
storePassword=myStorePassword
keyPassword=myKeyPassword
keyAlias=upload
storeFile=/path/to/upload-keystore.jks
app/build.gradle.kts
import java.io.FileInputStream
import java.util.Properties

val keystoreProperties = Properties().apply {
    load(FileInputStream(rootProject.file("keystore.properties")))
}

android {
    signingConfigs {
        create("release") {
            keyAlias = keystoreProperties["keyAlias"] as String
            keyPassword = keystoreProperties["keyPassword"] as String
            storeFile = file(keystoreProperties["storeFile"] as String)
            storePassword = keystoreProperties["storePassword"] as String
        }
    }
    buildTypes {
        release {
            isMinifyEnabled = true
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
            signingConfig = signingConfigs.getByName("release")
        }
    }
}

Сделайте резервную копию хранилища и обоих паролей. Если ключ загрузки потерян или утёк, создайте новый и запросите сброс ключа загрузки в Play Console; ключ подписи приложения остаётся прежним.

Код версии и целевой уровень API

versionCode должен быть больше, чем у любого загруженного бандла в любом треке; versionName видят пользователи. Оба значения находятся в defaultConfig, рядом с уровнями SDK:

app/build.gradle.kts
android {
    compileSdk = 36
    defaultConfig {
        applicationId = "com.yourcompany.app"
        targetSdk = 36
        versionCode = 2
        versionName = "1.0.1"
    }
}

С 31 августа 2026 года новые приложения и обновления должны быть нацелены на Android 16 (уровень API 36). Повышение targetSdk включает новое поведение платформы. Приложения, нацеленные на Android 15 и выше, отображаются от края до края, а в Android 16 отключить это уже нельзя, поэтому до начала теста проверьте, что экраны Compose правильно обрабатывают window insets.

Ловушки Kotlin и Compose

  • R8 удаляет то, что нужно рефлексии. С isMinifyEnabled = true модели сериализации, классы Retrofit или Gson и некоторые схемы внедрения зависимостей могут ломаться только в release. Добавьте правила в proguard-rules.pro и проверьте вариант release.
  • Сюрпризы режима от края до края. Контент под строкой состояния и панелью навигации закрывает кнопки. Используйте отступы Scaffold или модификаторы WindowInsets на каждом экране, который увидят тестировщики.
  • Отлаживаемый release. Если в типе сборки release стоит isDebuggable = true, Play Console отклонит бандл.
  • Секреты подписи в git. Пароли, записанные прямо в build.gradle.kts, оказываются в репозитории. Храните их в keystore.properties или в секретах CI.
  • Нативные библиотеки и страницы 16 КБ. Приложения только на Kotlin уже поддерживают страницы памяти 16 КБ, но код NDK и библиотеки с файлами .so нужно пересобрать или обновить. Play Console предупреждает об этом, а с 1 февраля 2027 года обновления без такой поддержки нельзя будет выпустить.
  • Проверка только debug. Тестировщики получают вариант release. Перед каждой загрузкой запускайте его хотя бы на одной свежей версии Android.

Читаемые трассировки: сопоставление R8 и нативные символы

Тестировщики запускают только релизный вариант, поэтому их сбои приходят из оптимизированного R8 кода с переименованными классами и методами. Сборка записывает сопоставление, которое отменяет это, в app/build/outputs/mapping/release/mapping.txt, перезаписывает его при каждой сборке и также кладёт в .aab.

  1. Доверьте деобфускацию Play Console

    Начиная с Android Gradle plugin 4.1, Play Console берёт файл сопоставления из загруженного бандла. Сбои в разделе Мониторинг и улучшение → Android Vitals → Сбои и ANR тогда показывают настоящие имена классов и методов.

  2. Храните копию для каждого выпуска

    Архивируйте mapping.txt с каждым загруженным кодом версии. Он понадобится для трассировок, которые тестировщики вставляют в отчёты, и для любых инструментов сбоев вне Google Play.

  3. Восстанавливайте трассировку вручную

    Запустите retrace из набора command-line tools с файлом сопоставления и файлом трассировки. Последние версии Android Studio также автоматически восстанавливают трассировки в Logcat.

Terminal (project root)
$ANDROID_HOME/cmdline-tools/latest/bin/retrace \
  app/build/outputs/mapping/release/mapping.txt trace.txt

Используете NDK? Задайте debugSymbolLevel в релизном типе сборки. SYMBOL_TABLE даёт имена функций в Play Console, FULL добавляет файлы и номера строк. В app bundle нативные символы включаются и загружаются автоматически.

app/build.gradle.kts
android {
    buildTypes {
        release {
            ndk {
                debugSymbolLevel = "FULL" // or "SYMBOL_TABLE"
            }
        }
    }
}

Если R8 оставляет неожиданный код или удаляет код, нужный для рефлексии, -whyareyoukeeping показывает путь от сохранённого класса до точки входа, а configuration.txt рядом с сопоставлением перечисляет все объединённые правила.

Коротко о Play Console: от закрытого теста до продакшена

Когда бандл Kotlin / Jetpack Compose собран и подписан, всё остальное происходит в Play Console и одинаково для любого фреймворка. Здесь краткий чек-лист; каждое меню и экран описаны в полном руководстве по Play Console.

  • Завершите настройку приложения на панели управления: политика конфиденциальности, доступ к приложению, реклама, возрастной рейтинг, целевая аудитория, безопасность данных и страница в Play Маркете.
  • Создайте выпуск для закрытого теста в разделе Тестирование и выпуск → Тестирование → Закрытое тестирование: выберите страны тестировщиков, загрузите .aab и отправьте на проверку.
  • Добавьте тестировщиков через Google Группу на вкладке Тестировщики и поделитесь ссылкой opt-in. Она заработает, когда у трека появится статус Опубликовано.
  • Держите не менее 12 тестировщиков с opt-in 14 дней подряд. Внутреннее тестирование не засчитывается, а у того, кто вышел и вернулся, отсчёт 14 дней начинается заново.
  • Выпустите хотя бы одно обновление во время теста и запишите, что нашли тестировщики и что вы изменили.
  • Подайте заявку на доступ к продакшену с панели управления и ответьте на три раздела о тесте, приложении и готовности. Решение принимает Google; никто не может гарантировать одобрение.

Учитывайте выбывших: наберите больше 12 тестировщиков, чтобы уход одного человека не сдвинул ваши сроки. Все шаги в Play Console.

Полное руководство по Play Console

Закрытый трек, Google Группа и ссылка opt-in, правило 12 тестировщиков / 14 дней и заявка на продакшен, шаг за шагом на одной странице.

Открыть шаги в Play Console

Тестируйте именно тот бандл и выпускайте обновления

Увеличьте versionCode, пересоберите бандл (Gradle или мастер Android Studio) и загрузите его в тот же закрытый трек.

Terminal
./gradlew bundleRelease

Чтобы установить бандл, который вы собираетесь загрузить, сгенерируйте из него APK для конкретного устройства с помощью bundletool, подписав ключом загрузки. Это ближе всего к тому, что доставляет Google Play, включая разделение по плотности экрана, языку и ABI:

Terminal
bundletool build-apks --connected-device \
  --bundle=app/build/outputs/bundle/release/app-release.aab --output=app.apks \
  --ks=/path/to/upload-keystore.jks --ks-key-alias=upload
bundletool install-apks --apks=app.apks

Для быстрых проверок вашей командой внутренний обмен приложениями в Play Console принимает любой код версии и даёт ссылку на скачивание для 100 человек максимум. Такие загрузки не могут входить в тестовый трек и не заменяют закрытый тест: ваши 12 тестировщиков всегда устанавливают приложение из закрытого трека.

Частые вопросы

Нужно ли загружать mapping.txt самому?

Не для app bundle, собранных с Android Gradle plugin 4.1 или новее: Play Console берёт его из .aab. Для APK нужна ручная загрузка, а инструментам сбоев вне Google Play нужна своя копия, так что архивируйте файл в любом случае.

Обязательна ли минификация?

Нет. isMinifyEnabled = true необязателен: он сжимает и обфусцирует код, и это же самая частая причина, по которой релизная сборка падает, а отладочная работает. Если включаете его, тестируйте релизный вариант перед каждой загрузкой.

Нужно ли что-то делать в Kotlin-приложении для страниц памяти 16 КБ?

Приложения только на Kotlin или Java уже поддерживают страницы 16 КБ. Если есть код NDK или библиотеки с файлами .so, используйте Android Gradle plugin 8.5.1 или новее и NDK r28 или новее, обновите эти библиотеки и протестируйте на образе эмулятора со страницами 16 КБ.

Стоит ли сначала провести внутреннее тестирование?

Можно. Внутреннее тестирование быстро настраивается и подходит для smoke-теста с командой, но не засчитывается в правило 12 тестировщиков, так что не позволяйте ему задерживать закрытый тест.

Источники

Технические детали сверены с официальной документацией ниже. Меню и значения по умолчанию меняются от версии к версии; если сомневаетесь, ориентируйтесь на официальную страницу.

Впервые слышите о правиле 12 тестировщиков?

Общее руководство объясняет требование Google, как день за днём проходит кампания TestBunny и что мы можем и не можем гарантировать.

Читать общее руководство

Нужны 12 настоящих тестировщиков на 14 дней?

Добавьте приложение и ссылку на закрытое тестирование, выберите Starter (15 тестировщиков) или Pro (25 тестировщиков) и следите за активностью каждого тестировщика по дням в своей панели.

TestBunny не связан с Google. Тестировщики получают кредиты, а не деньги. Никто не может гарантировать решение Google о доступе к продакшену, и мы тоже.