Skip to main content
Version: Next

Google Play 스토어에 앱 배포

안드로이드는 모든 앱이 설치되기 전에 디지털 인증서로 서명되어야 한다. Google Play 스토어를 통해 안드로이드 애플리케이션을 배포하려면 릴리스 키로 서명해야 하며, 이후 모든 업데이트에도 동일한 키를 사용해야 한다. 2017년부터 Google Play의 앱 서명 기능 덕분에 Google Play가 릴리스 서명을 자동으로 관리할 수 있게 되었다. 그러나 애플리케이션 바이너리를 Google Play에 업로드하기 전에는 업로드 키로 서명해야 한다. 안드로이드 개발자 문서의 애플리케이션 서명 페이지에서 이 주제를 자세히 설명한다. 이 가이드는 해당 과정을 간략히 다루며, JavaScript 번들을 패키징하는 데 필요한 단계도 안내한다.

info

Expo를 사용 중이라면 앱 스토어 배포 가이드를 참고해 Google Play 스토어에 앱을 빌드하고 제출할 수 있다. 이 가이드는 모든 React Native 앱에 적용되며 배포 과정을 자동화한다.

업로드 키 생성하기

keytool을 사용해 개인 서명 키를 생성할 수 있다.

윈도우 환경 설정

윈도우에서 keytool을 실행하려면 관리자 권한으로 C:\Program Files\Java\jdkx.x.x_x\bin 디렉터리에서 실행해야 한다.

shell
keytool -genkeypair -v -storetype PKCS12 -keystore my-upload-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000

이 명령어를 실행하면 키스토어와 키에 대한 비밀번호, 그리고 Distinguished Name 필드 값을 입력하라는 메시지가 나타난다. 이후 my-upload-key.keystore라는 파일로 키스토어가 생성된다.

이 키스토어는 10000일 동안 유효한 단일 키를 포함한다. alias는 나중에 앱을 서명할 때 사용할 이름이므로, 반드시 기억해 두어야 한다.

macOS

macOS에서 JDK bin 폴더의 위치를 모르겠다면, 다음 명령어를 실행해 위치를 확인한다.

shell
/usr/libexec/java_home

이 명령어는 JDK 디렉터리를 출력하며, 출력 결과는 다음과 같은 형태일 것이다.

shell
/Library/Java/JavaVirtualMachines/jdkX.X.X_XXX.jdk/Contents/Home

cd /your/jdk/path 명령어를 사용해 해당 디렉터리로 이동한 후, 아래와 같이 sudo 권한으로 keytool 명령어를 실행한다.

shell
sudo keytool -genkey -v -keystore my-upload-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
caution

keystore 파일을 비공개로 유지해야 한다. 업로드 키를 분실하거나 키가 유출된 경우, 이 가이드를 따라 조치를 취한다.

Gradle 변수 설정하기

  1. 프로젝트 폴더 내 android/app 디렉토리에 my-upload-key.keystore 파일을 위치시킨다.
  2. ~/.gradle/gradle.properties 또는 android/gradle.properties 파일을 편집하고 다음 내용을 추가한다. (***** 부분을 실제 keystore 비밀번호, alias, 키 비밀번호로 대체)
MYAPP_UPLOAD_STORE_FILE=my-upload-key.keystore
MYAPP_UPLOAD_KEY_ALIAS=my-key-alias
MYAPP_UPLOAD_STORE_PASSWORD=*****
MYAPP_UPLOAD_KEY_PASSWORD=*****

이 변수들은 전역 Gradle 변수로 설정되며, 이후 Gradle 설정에서 앱 서명 시 사용할 수 있다.

git 사용 시 참고 사항

위 Gradle 변수를 android/gradle.properties 대신 ~/.gradle/gradle.properties에 저장하면 git에 체크인되는 것을 방지할 수 있다. 사용자 홈 디렉토리에 ~/.gradle/gradle.properties 파일을 먼저 생성해야 할 수도 있다.

보안 관련 참고 사항

macOS를 사용 중이고, 비밀번호를 평문으로 저장하고 싶지 않다면, Keychain Access 앱에 자격 증명을 저장할 수 있다. 이 경우 ~/.gradle/gradle.properties 파일의 마지막 두 줄을 생략해도 된다.

앱의 Gradle 설정에 서명 설정 추가하기

릴리스 빌드를 업로드 키로 서명하기 위해 마지막으로 해야 할 설정 작업이다. 프로젝트 폴더의 android/app/build.gradle 파일을 편집하고, 다음과 같이 서명 설정을 추가한다.

groovy
...
android {
...
defaultConfig { ... }
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
}
}
}
...

릴리스 AAB 생성하기

터미널에서 다음 명령어를 실행한다:

shell
npx react-native build-android --mode=release

이 명령어는 내부적으로 Gradle의 bundleRelease를 사용해 앱 실행에 필요한 모든 자바스크립트를 AAB(Android App Bundle)로 묶는다. 자바스크립트 번들링 방식이나 드로어블 리소스의 구조를 변경해야 한다면(예: 기본 파일/폴더 이름이나 프로젝트 구조를 변경한 경우), android/app/build.gradle 파일을 확인해 필요한 수정을 반영한다.

note

gradle.properties 파일에 org.gradle.configureondemand=true가 포함되지 않았는지 확인한다. 이 설정이 있으면 릴리스 빌드 시 자바스크립트와 에셋이 앱 바이너리에 포함되지 않을 수 있다.

생성된 AAB 파일은 android/app/build/outputs/bundle/release/app-release.aab 경로에서 확인할 수 있으며, 바로 Google Play에 업로드할 수 있다.

Google Play에서 AAB 형식을 수락하려면 Google Play Console에서 앱에 대해 Google Play 앱 서명을 설정해야 한다. 기존 앱을 업데이트하는 경우 Google Play 앱 서명을 사용하지 않았다면 마이그레이션 섹션을 참고해 설정 변경 방법을 확인한다.

앱의 릴리스 빌드 테스트

Play Store에 릴리스 빌드를 업로드하기 전에 철저히 테스트한다. 먼저 기존에 설치된 앱의 이전 버전을 모두 제거한다. 프로젝트 루트에서 다음 커맨드를 사용해 디바이스에 설치한다.

shell
npm run android -- --mode="release"

--mode release는 앞서 설명한 서명 설정을 완료한 경우에만 사용할 수 있다.

실행 중인 번들러 인스턴스를 종료해도 된다. 프레임워크와 자바스크립트 코드가 모두 APK의 assets에 번들링되어 있기 때문이다.

다른 스토어에 배포하기

기본적으로 생성된 APK는 x86, x86_64, ARMv7a, ARM64-v8a CPU 아키텍처에 대한 네이티브 코드를 모두 포함한다. 이렇게 하면 거의 모든 Android 기기에서 실행 가능한 APK를 공유하기 쉽다. 하지만 이 방식은 각 기기에서 사용되지 않는 네이티브 코드가 포함되어 APK 크기가 불필요하게 커진다는 단점이 있다.

각 CPU 아키텍처별로 APK를 생성하려면 android/app/build.gradle 파일에 다음 코드를 추가한다:

diff
android {

splits {
abi {
reset()
enable true
universalApk false
include "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
}
}

}

이렇게 생성된 파일은 Amazon AppStoreF-Droid와 같이 기기 타겟팅을 지원하는 마켓에 업로드하면 사용자는 자동으로 적절한 APK를 받을 수 있다. APKFiles와 같이 단일 앱에 대해 여러 APK를 지원하지 않는 마켓에 업로드하려면 universalApk falsetrue로 변경해 모든 CPU 아키텍처를 포함한 기본 유니버설 APK를 생성하면 된다.

공식 Android 문서에서 제안한 것처럼, 별도의 버전 코드를 구성해야 한다는 점에 유의한다.

APK 크기를 줄이기 위해 Proguard 활성화하기 (선택 사항)

Proguard는 APK 크기를 약간 줄일 수 있는 도구다. 이 도구는 앱에서 사용하지 않는 React Native 자바 바이트코드와 그 의존성을 제거함으로써 이를 달성한다.

중요

Proguard를 활성화했다면 앱을 철저히 테스트해야 한다. Proguard는 사용 중인 각 네이티브 라이브러리에 맞는 설정이 필요한 경우가 많다. app/proguard-rules.pro 파일을 참고하자.

Proguard를 활성화하려면 android/app/build.gradle 파일을 수정한다:

groovy
/**
* 릴리스 빌드에서 자바 바이트코드를 줄이기 위해 Proguard를 실행한다.
*/
def enableProguardInReleaseBuilds = true

구글 플레이 앱 서명을 사용하도록 이전 안드로이드 React Native 앱 마이그레이션

이전 버전의 React Native에서 마이그레이션하는 경우, 여러분의 앱은 아마 구글 플레이 앱 서명 기능을 사용하지 않을 것이다. 자동 앱 분할과 같은 기능을 활용하기 위해 이 기능을 활성화할 것을 권장한다. 기존 서명 방식에서 마이그레이션하려면 먼저 새로운 업로드 키 생성부터 시작해야 한다. 그런 다음 android/app/build.gradle 파일의 릴리스 서명 설정을 릴리스 키 대신 업로드 키를 사용하도록 변경한다(그레이들 설정에 서명 추가 섹션 참조). 이 작업을 완료한 후에는 구글 플레이 도움말 웹사이트의 지침에 따라 기존 릴리스 키를 구글 플레이로 전송해야 한다.

기본 권한 설정

기본적으로 INTERNET 권한은 거의 모든 앱에서 사용되기 때문에 자동으로 추가된다. 디버그 모드에서는 SYSTEM_ALERT_WINDOW 권한이 APK에 포함되지만, 프로덕션 빌드에서는 제거된다.