BuildType
프로젝트를 개발하다가 보면, debug 모드로 개발을 하다가, 릴리즈 버전으로 빌드해서 테스트를 진행하고자 할 때 Build Variants에서 release를 클릭하여 release 모드로 빌드하는 경험을 했을 것이라고 생각합니다.
이는 BuildType 변경을 통해서 “00용” 앱을 빌드할수 있게 하는 기능입니다.
- debug : 개발용
- release : 배포용
Gradle에서 BuildTypes은 빌드 목적을 구성하여 단일 프로젝트에서 다양한 목적의 앱을 만드는 방법을 제공합니다.
기본적으로 모듈을 만들게 되면 gradle에서 자동 생성된, 다음을 확인할 수 있습니다.
android {
namespace = "com.example.buildvariants"
compileSdk = 34
defaultConfig {
applicationId = "com.example.buildvariants"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
/*
debug {
applicationIdSuffix = ".debug"
isDebuggable = true
}
*/
}
}
gradle에서 android 블록내에 빌드 유형을 만들어져 있습니다.
새로운 모듈을 만들면 디버그 빌드 유형과 릴리즈 빌드 유형이 자동으로 생성됩니다.
하지만 debug 유형은 보이지가 않는데, default 제공되서 그런가봅니다.
기본으로 제공되는 debug 빌드 유형을 재정의하기 위해서는 위의 주석을 풀고서 지정하면됩니다.
사용자 정의 빌드 유형을 추가하려면 buildTypes블록 내부에 새롭게 종류를 정의하면 됩니다.
새로운 빌드 유형인 staging를 추가해보겠습니다.
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
create("staging") {
initWith(getByName("debug")) // debug 환경으로 staging 환경을 초기화.
manifestPlaceholders["hostName"] = "internal.example.com"
applicationIdSuffix = ".staging"
}
}
applicationIdSuffix는 지정하면 applicationId 뒤에 붙여지게 됩니다. 식별자의 역할을 합니다. 어떤 build유형으로 빌드를 했는지 확인하는 용도로 사용할 수 있으며, applicationId가 달라지기 떄문에 중복되지않아 하나의 폰에서 여러가지 빌드 타입을 설치할 수 있습니다.
예제에서 staging이라는 용어를 사용했는데요. 어떤 의미의 빌드 종류인지 찾아보았습니다.
staging을 검색하면 서버에 관련한 글을 많이 찾을 수 있었습니다.
서버에서는 LocalServer , 개발 서버, 스테이징 서버, 운영 서버 등등 종류가 나뉜다고 합니다.
- LocalServer (로컬 서버)
- 개발자들이 처음으로 실행시키는 서버. ex) local host
- Development Server (개발 서버)
- 개인 개발환경이 아닌, 1개의 통합된 환경으로 테스트 할 있는 서버.
- Staging Server(스테이징 서버)
- 테스트 서버, QA 서버 등등으로 불리기도 하며 운영 서버 환경와 비슷하게 환경을 맞춘 다음, 성능, 버그 등등 테스트하는 서버.
- Production Server(운영 서버)
- 실질적으로 운영을 하기 위한 서버.
실제 프로젝트를 진행하게 되면, 개발 서버와 운영서버의 URL이 다르고 debug 모드에서는 개발 서버 URL의 API를 호출하고, 앱을 배포할 때는 이를 운영서버의 URL로 변경해서 앱을 추출하는 경험을 해보셨을겁니다.
따라서 Staging 빌드 환경은 앱에서도 성능 테스트 등등을 하기 위한 build 종류 중 하나라고 생각됩니다.
다음으로는 빌드 유형이 아닌 제품 버전을 추가하는 방법을 알아보겠습니다.
Product Flavors
BuildType은 Build의 종류를 의미한다면, 제품의 종류로 나뉘는 것을 ProductFlavors라고 합니다.
예를 들어 “디버그용 00지역 지점 기기” 라고 했을 때
BuildType에서는 Debug가 들어가고 00지역은 제품의 종류라고 할 수 있습니다.
android 블록안에 productFlavors 블록을 생성해주면 제품 버전을 구성할 수 있습니다.
android {
...
defaultConfig {
applicationId "example"
minSdk 26
targetSdk 34
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
}
buildTypes {
debug {...}
release {...}
}
// Specifies one flavor dimension.
flavorDimensions += "version"
productFlavors {
demo {
// Assigns this product flavor to the "version" flavor dimension.
// If you are using only one dimension, this property is optional,
// and the plugin automatically assigns all the module's flavors to
// that dimension.
dimension = "version"
applicationIdSuffix = ".demo"
versionNameSuffix = "-demo"
}
full {
dimension = "version"
applicationIdSuffix = ".full"
versionNameSuffix = "-full"
}
}
}
위에서 BuildType을 정의한 것과 비슷하게 만들 수 있습니다.
BuildType과 다르게 flavorDimension과 dimension 용어들이 보입니다. 직역하면 “차원”의 의미인데 “00지역 지점 기기”로 Dimension을 지정하자면, “location”이 dimension으로 지정할 수 있을 것입니다. 말 그대로 이 제품 버전들이 묶이는 큰 범위를 의미합니다.
flavorDiemsions를 생성하여 그룹 flavor를 생성합니다. 추가적인 버전들은 해당하는 그룹 flavor내부에 할당되어야합니다.
defaultConfig는 ProductFlavor class에 속하기 때문에 productFlavor내부에서 defaultConfig와 동일한 속성을 사용할 수 있습니다.
따라서 flavor를 통해서 version code나 max,min sdk 버전 등등을 제어할 수도 있습니다.
BuildType과 ProductFlavor가 모두 2가지씩 사용한다고 가정하면
- BuildType[0] + ProductFlavor[0]
- BuildType[0] + ProductFlavor[1]
- BuildType[1] + ProductFlavor[0]
- BuildType[1] + ProductFlavor[1]
총 4가지의 빌드 및 제품 종류의 환경에서 앱을 빌드할 수 있게 됩니다.
또한 위의 2가지와 properties를 조합하게 되면, 빌드 타입이나 productFlavor에 따라서
각각 다른 BuildConfig에서 값을 가져올 수 있습니다.
buildTypes {
debug {
applicationIdSuffix ".dev"
buildConfigField "String", "server_url", "\"${getLocalProperty("dev_server_url")}\""
buildConfigField "String", "websocket_url", "\"${getLocalProperty("dev_websocket_url")}\""
}
product{
applicationIdSuffix ".product"
buildConfigField "String", "server_url", "\"${getLocalProperty("product_server_url")}\""
buildConfigField "String", "websocket_url", "\"${getLocalProperty("product_websocket_url")}\""
}
}
flavorDimensions += "device_uid"
productFlavors {
dev_01 {
dimension "device_uid"
applicationIdSuffix =".dev"
buildConfigField("String", "uid", "\"${getLocalProperty("dev_01")}\"")
}
dev_02 {
dimension "device_uid"
applicationIdSuffix =".dev"
buildConfigField("String", "uid", "\"${getLocalProperty("dev_02")}\"")
}
product_01{
dimension "device_uid"
applicationIdSuffix =".product"
buildConfigField("String", "uid", "\"${getLocalProperty("product_01")}\"")
}
product_02{
dimension "device_uid"
applicationIdSuffix =".product"
buildConfigField("String", "uid", "\"${getLocalProperty("product_02")}\"")
}
}
결론
프로젝트를 진행할때마다, 개발 ↔ 배포 또는 제품별로 일일히 넣어준 상태로 앱을 빌드해보곤 했었는데 BuildType과 ProductFlavor를 통해서 간단히 다양한 환경으로 앱을 빌드 해볼 수 있었습니다. 사용해보시는 것을 추천 드립니다.
'Android' 카테고리의 다른 글
setContentView in Activity (0) | 2023.03.02 |
---|---|
Activity (0) | 2023.02.22 |
Android에서 잠금화면 만들어보자 (0) | 2023.01.19 |
Notification을 수신해보자! (0) | 2022.12.08 |
LiveData를 뜯어보자 (0) | 2022.11.23 |