Manage remote repositories
새 안드로이드 스튜디오 프로젝트에서는 레포지토리 관련된 걸 settings.gradle에서 관리한다. 로컬 라이브러리나 파일이든, 리모트 레포지토리든, dependencyResolutionManagement{ } 에 넣어준다. 기본적으로 프로젝트를 생성하면 아래와 같이 구글 Maven 레포지토리와 Maven central 레포지토리를 포함하고 있다.
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
로컬 레포지토리를 사용하려면 다음과 같이 mavenLocal()을 사용한다.
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
mavenLocal()
}
}
또는 다음과 같이 특정 레포지토리를 직접 추가할 수 있다.
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
maven(url = "https://repo.example.com/maven2")
maven(url = "file://local/repo/")
ivy(url = "https://repo.example.com/ivy")
}
}
보다 자세한 내용은 gradle의 레포지토리 가이드를 참조 하라고 함.
Configure build variants
Configure build types
빌드 타입은 release, debug와 같은 구분을 말한다. 빌드 타입을 구성(configure)하는 것은 모듈레벨의 build.gradle.kts의 android { } 블럭에서 기술한다. 새 프로젝트를 생성하면, 기본적으로 ‘release’ 타입을 생성해준다. 안드로이드 스튜디오에서는 기본적으로 디버그가 가능한데, 아마도 디버그로 실행시 자동으로 설정되는 것으로 보인다. 이를 다음과 같이 명시적으로 표시해줄 수 있다.
buildTypes {
getByName("release") {
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
}
getByName("debug") {
applicationIdSuffix = ".debug"
isDebuggable = true
}
/**
* The `initWith` property lets you copy configurations from other build types,
* then configure only the settings you want to change. This one copies the debug build
* type, and then changes the manifest placeholder and application ID.
*/
create("staging") {
initWith(getByName("debug"))
manifestPlaceholders["hostName"] = "internal.example.com"
applicationIdSuffix = ".debugStaging"
}
}
디버그 빌드도 포함시켰으며, 그 안에 “isDebuggable = true”로 명시해준걸 볼 수 있다. 또한, 커스텀 빌드로 “staging”이 추가된 것도 볼 수 있다. ‘initWith( )’는 베이스가 되는 빌드타입을 말한다.
Configure product flavors
product flavors는 demo, paid, free 등의 버전 구분을 의미한다. 빌드 타입과 유사하게 build.gradle.kts 내에서 productFlavors{ } 내부에 기술하게 된다.
모든 product flavor들은 명명된 flavor dimension에 속해야 한다. flavor dimension은 product flavor들의 그룹을 의미한다. 만약, 단 하나의 flavor dimension만 지정하는 경우, AGP에서 자동으로 모듈의 모든 flavor들을 그 flavor dimension에 할당한다.
다음의 예제는 “version”으로 명명된 flavor dimension을 생성하고, 여기에 “demo”와 “full” 두가지 이름의 product flavor를 추가하는 내용이다.
android {
...
defaultConfig {...}
buildTypes {
getByName("debug"){...}
getByName("release"){...}
}
// Specifies one flavor dimension.
flavorDimensions += "version"
productFlavors {
create("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"
}
create("full") {
dimension = "version"
applicationIdSuffix = ".full"
versionNameSuffix = "-full"
}
}
}
빌드 스크립트를 작성하고 sync now를 클릭해서 싱크가 이루어지면, gradle은 자동으로 build type과 product flavor에 기반해 build variant를 생성하게 된다. 그 이름은 <product-flavor><Build-Type>의 형태이다. 위의 스크립트를 생각한다면, demoDebug, demoRelease, fullDebug, fullRelease와 같다.
build variants를 위해 application ID 변경하기
기본적으로 defaultConfig { } 에 있는 applicationid속성을 사용하게 된다. 별도로 “free”, “pro”버전을 플레이스토어에 보여주고 싶다면, 다른 application ID를 가진 build variant를 생성해야 한다. 이는 applicationIdSuffix 속성을 지정해줌 으로서 가능하다.
android {
defaultConfig {
applicationId = "com.example.myapp"
}
productFlavors {
create("free") {
applicationIdSuffix = ".free"
}
create("pro") {
applicationIdSuffix = ".pro"
}
}
}
위와같이 지정해주면, “free” flavor에 대해 “com.example.myapp.free”, “pro” flavor에 대해 “com.example.myapp.pro”의 application ID가 지정된다.
빌드 타입도 적용가능하다.
android {
...
buildTypes {
getByName("debug") {
applicationIdSuffix = ".debug"
}
}
}
앞서 말했듯, flavor가 먼저 나오고 build type이 뒤에 나오므로, “free debug” build variant에 대해 “com.example.myapp.free.debug”와 같은 application ID가 주어지게 된다. 이는 단일 디바이스에서 디버그와 릴리즈 버전을 동시에 실행 가능하게 해준다. 두개의 앱이 같은 application ID를 가질 수 없기 때문이다.
product flavors 와 flavor dimensions 의 조합 만들기
예를 들어 “full” 과 “demo” 라는 flavor에 대해 API 레벨별로 빌드를 따로 만들고 싶을 수가 있다. 이런 경우에 flavor dimensions를 이용하여 가능해진다. 빌드타입도 당연히 조합된다. 다음의 예제를 보자.
android {
...
buildTypes {
getByName("debug") {...}
getByName("release") {...}
}
// Specifies the flavor dimensions you want to use. The order in which you
// list the dimensions determines their priority, from highest to lowest,
// when Gradle merges variant sources and configurations. You must assign
// each product flavor you configure to one of the flavor dimensions.
flavorDimensions += listOf("api", "mode")
productFlavors {
create("demo") {
// Assigns this product flavor to the "mode" flavor dimension.
dimension = "mode"
...
}
create("full") {
dimension = "mode"
...
}
// Configurations in the "api" product flavors override those in "mode"
// flavors and the defaultConfig block. Gradle determines the priority
// between flavor dimensions based on the order in which they appear next
// to the flavorDimensions property, with the first dimension having a higher
// priority than the second, and so on.
create("minApi24") {
dimension = "api"
minSdk = 24
// To ensure the target device receives the version of the app with
// the highest compatible API level, assign version codes in increasing
// value with API level.
versionCode = 30000 + (android.defaultConfig.versionCode ?: 0)
versionNameSuffix = "-minApi24"
...
}
create("minApi23") {
dimension = "api"
minSdk = 23
versionCode = 20000 + (android.defaultConfig.versionCode ?: 0)
versionNameSuffix = "-minApi23"
...
}
create("minApi21") {
dimension = "api"
minSdk = 21
versionCode = 10000 + (android.defaultConfig.versionCode ?: 0)
versionNameSuffix = "-minApi21"
...
}
}
}
...
예제를 보면, flavor dimension으로 “api” 와 “mode”를 만들었으며, “api” dimension 그룹에 각 지원 api별 flavor를 만들고, “mode” 그룹에 “demo” 와 “full”을 만들었다. 이렇게 flavor dimension이 다르게 되면, gradle에서 다른 flavor dimension들에 대해 각각 조합을 만들어 낸다. 위 예제의 경우, [minApi24, minApi23, minApi21][Demo, Full][Debug, Release] 로 조합되어 12개의 build variant가 생성된다.
…아… Code block pro 또 에러난다. 다음 포스팅에서 계속.