Соберите релизный app bundle
React Native упаковывает JavaScript внутрь нативной сборки Android, поэтому релизный .aab собирает Gradle. Сначала настройте подпись (следующий раздел), затем:
Проверьте имя пакета
applicationIdвandroid/app/build.gradleстановится постоянным после загрузки в Google Play. Убедитесь, что это нужное значение.Соберите
В корне проекта выполните
npx react-native build-android --mode=releaseили вызовите Gradle напрямую, как ниже. Оба способа запускают задачуbundleReleaseи упаковывают JavaScript в приложение.Найдите файл
Бандл сохраняется в
android/app/build/outputs/bundle/release/app-release.aab.Проверьте релизную сборку
Удалите отладочное приложение и установите вариант release на реальное устройство второй командой ниже. Сбои, которые бывают только в release, проявятся здесь, а не в Play Console.
cd android
./gradlew bundleReleasenpm run android -- --mode="release"Не задавайте org.gradle.configureondemand=true в gradle.properties. Из-за этого релизная сборка может пропустить упаковку JavaScript и ресурсов, и тестировщики получат приложение, которое не запускается.
Ключ загрузки и подписание приложений в Google Play
Для новых приложений Google Play требует подписание приложений в Google Play: ключ подписи приложения хранит Google, а загрузки вы подписываете ключом загрузки. Создайте его утилитой keytool, которая входит в JDK:
keytool -genkeypair -v -storetype PKCS12 -keystore my-upload-key.keystore \
-alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000Переместите файл в android/app/, а учётные данные запишите в ~/.gradle/gradle.properties, чтобы они никогда не попали в git:
MYAPP_UPLOAD_STORE_FILE=my-upload-key.keystore
MYAPP_UPLOAD_KEY_ALIAS=my-key-alias
MYAPP_UPLOAD_STORE_PASSWORD=*****
MYAPP_UPLOAD_KEY_PASSWORD=*****Затем добавьте конфигурацию подписи release в android/app/build.gradle и используйте её в типе сборки release. В шаблоне release подписывается отладочным ключом, пока вы это не измените:
android {
signingConfigs {
release {
if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
storeFile file(MYAPP_UPLOAD_STORE_FILE)
storePassword MYAPP_UPLOAD_STORE_PASSWORD
keyAlias MYAPP_UPLOAD_KEY_ALIAS
keyPassword MYAPP_UPLOAD_KEY_PASSWORD
}
}
}
buildTypes {
release {
// ...
signingConfig signingConfigs.release
}
}
}Код версии и целевой уровень API
У каждой загрузки versionCode должен быть больше, чем у всего, что вы загружали раньше. В bare-проекте он находится в android/app/build.gradle; versionName — это подпись, которую видят пользователи:
android {
defaultConfig {
versionCode 2
versionName "1.0.1"
}
}С 31 августа 2026 года новые приложения и обновления должны быть нацелены на Android 16 (уровень API 36). Уровни SDK заданы в блоке ext файла android/build.gradle (compileSdkVersion, targetSdkVersion). Новые версии React Native их повышают. На старой версии обычно надёжнее обновить React Native, чем поднять только targetSdkVersion, ведь совместимыми должны быть и ваши нативные библиотеки.
Ловушки React Native
- Бандл с отладочной подписью. Если забыть переключить тип сборки release на
signingConfigs.release, Play Console отклонит загрузку как подписанную отладочным ключом. - Сюрпризы R8/ProGuard. С
enableProguardInReleaseBuilds = trueбиблиотеки, использующие рефлексию, могут падать только в release. Добавьте их правила keep вandroid/app/proguard-rules.proи проверьте релизную сборку на устройстве. - Нечитаемые отчёты о сбоях. Hermes, движок по умолчанию, выполняет заранее скомпилированный байт-код, и релизные трассировки указывают на скомпилированный бандл. Сохраняйте source maps каждой загруженной сборки, чтобы расшифровывать то, что присылают тестировщики.
- Приложение ищет Metro. Если релизная сборка пытается подключиться к серверу разработки, значит JavaScript не был упакован. Проверьте настройку
configureondemandи пересоберите. - Нативные модули и страницы 16 КБ. Библиотеки с нативными файлами
.soдолжны поддерживать страницы памяти 16 КБ. Play Console предупреждает об этом, а с 1 февраля 2027 года обновления без такой поддержки нельзя будет выпустить. Обновите их до начала теста. - Потерянное хранилище ключей. Сделайте резервную копию хранилища и паролей. Сброс ключа загрузки можно запросить в Play Console, но это займёт время, которое не хочется терять посреди теста.
Символизируйте сбои от тестировщиков
Сбой JavaScript в релизной сборке приходит к вам как позиция в байт-коде Hermes, например p@1:132161, и сама по себе ничего не говорит. React Native по умолчанию создаёт source maps для релизных сборок Android; важно сохранять правильную карту для каждого загруженного бандла.
Архивируйте source map
После каждой релизной сборки копируйте карту из
android/app/build/generated/sourcemaps/react/release/и подписывайте её кодом версии. Она должна точно соответствовать коммиту упавшей сборки: даже небольшие изменения кода сдвигают смещения.Запустите metro-symbolicate
Сохраните трассировку тестировщика в файл или прочитайте её прямо из
adb logcatи пропустите черезmetro-symbolicateс этой картой. Инструмент превращает смещения байт-кода обратно в имена файлов, строки и функции.Проверьте нативные кадры в Play Console
Сбои в Java- или Kotlin-коде нативных модулей появляются в разделе Мониторинг и улучшение → Android Vitals → Сбои и ANR. При включённом R8 файл сопоставления внутри
.aabделает их читаемыми без отдельной загрузки.
# From a saved stack trace
npx metro-symbolicate android/app/build/generated/sourcemaps/react/release/index.android.bundle.map < stacktrace.txt
# From a connected device
adb logcat -d | npx metro-symbolicate android/app/build/generated/sourcemaps/react/release/index.android.bundle.mapЕсли metro-symbolicate сразу завершается без вывода, значит, он не получил входных данных: передавайте трассировку через конвейер или перенаправление, а не вводом в терминале.
Коротко о Play Console: от закрытого теста до продакшена
Когда бандл React Native собран и подписан, всё остальное происходит в 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 дней и заявка на продакшен, шаг за шагом на одной странице.
Выпускайте обновления во время теста
В React Native: увеличьте versionCode (и versionName), пересоберите и загрузите новый бандл в тот же закрытый трек.
cd android
./gradlew bundleReleaseУдалите отладочное приложение, прежде чем устанавливать релизный вариант командой npm run android -- --mode="release": Android не заменит приложение, подписанное другим ключом. Повторяйте эту проверку перед каждой загрузкой, потому что проблемы только релизной сборки, например отсутствующие правила keep, в отладке не проявляются.
Обновления JavaScript по воздуху — серая зона, о которой спрашивают многие команды. Политика Google Play о злоупотреблении устройствами и сетями запрещает приложению обновляться в обход Google Play, но это ограничение не распространяется на код, который выполняется в виртуальной машине или интерпретаторе, например JavaScript. Нативный код, новые разрешения и нативные модули всегда требуют нового бандла через Google Play.
- Основной путь — закрытый трек. Новый
versionCodeв закрытом треке доходит до каждого тестировщика с opt-in через Google Play и виден в истории выпусков. - Не трогайте нативные зависимости. Обновление React Native или нативного модуля посреди теста меняет гораздо больше, чем исправляемая ошибка. Делайте это до теста или после получения доступа к продакшену.
- Одна карта на выпуск. Каждая пересборка даёт новую source map. Храните её вместе с кодом версии, иначе следующий отчёт о сбое этой версии не удастся расшифровать.
Частые вопросы
Нужен ли Hermes для Google Play?
Нет, но это движок React Native по умолчанию, и с ним выходит большинство приложений. Он заранее компилирует JavaScript в байт-код: это ускоряет запуск и объясняет, почему релизным трассировкам нужна source map.
Какой файл загружать в Play Console?
Бандл из android/app/build/outputs/bundle/release/app-release.aab. Команда npx react-native build-android --mode=release запускает задачу Gradle bundleRelease и упаковывает в него весь ваш JavaScript.
Почему после повышения targetSdk интерфейс заезжает под строку состояния?
Приложения, нацеленные на Android 15 (уровень API 35) и выше, отображаются от края до края. react-native-safe-area-context уже решает это; без этой библиотеки добавьте отступы безопасной зоны на каждый экран до того, как его увидят тестировщики.
Поддерживает ли React Native страницы памяти 16 КБ?
Да, начиная с React Native 0.77. Более старые версии и нативные модули со своими файлами .so могут не поддерживать. Обновляйтесь до начала теста, а не посреди него.
Источники
Технические детали сверены с официальной документацией ниже. Меню и значения по умолчанию меняются от версии к версии; если сомневаетесь, ориентируйтесь на официальную страницу.
- React Native: Publishing to Google Play Store
- Android Developers: Sign your app
- Android Developers: Target API level requirements
- Android Developers: Support 16 KB page sizes
- React Native: Debugging release builds
- React Native 0.77 release notes (16 KB pages, edge-to-edge)
- Play Policy: Device and Network Abuse
- Play Console Help: App testing requirements for new personal developer accounts
- Play Console Help: Set up an open, closed, or internal test
- Play Console Help: Deobfuscate or symbolicate crash stack traces
Впервые слышите о правиле 12 тестировщиков?
Общее руководство объясняет требование Google, как день за днём проходит кампания TestBunny и что мы можем и не можем гарантировать.
Читать общее руководство