Uing? Uing!!

[안드로이드 팁] Build Varients: 같은 프로젝트로 두 개 이상의 앱 빌드하기(BuildTypes & ProductFlavors) 본문

Android

[안드로이드 팁] Build Varients: 같은 프로젝트로 두 개 이상의 앱 빌드하기(BuildTypes & ProductFlavors)

Uing!! 2021. 10. 20. 01:17
반응형

기본적으로, 하나의 패키지명은 하나의 고유한 앱을 의미한다. 

그리고, 같은 패키지명을 가진 앱은 같은 기기에 설치될 수 없다.

그러므로, 같은 앱은 기기에 두 개 이상 설치할 수 없다.

 

하지만 같은 종류의 앱을 여러 타입, 또는 여러 버전으로 나누어 빌드하고 싶을 수도 있다.

아래 두 상황을 대표적인 예로 들 수 있다. (공식 문서에서도 이 두 가지를 예로 들어 설명한다.)

 

1) 출시용과 디버그용 앱을 분리하기 위해서

  - 이 경우 디버그용 앱에는 몇 가지 기능들이 추가될 것이다.

2) 무료앱과 유료앱을 분리하기 위해서

  - 이 경우 무료앱에서는 유료앱의 기능들이 잠김 상태로 표시될 것이다.

 

이런 경우에 사용할 수 있는 것이 Build Varients(빌드 변형)이다.

 

 

Build Varients(빌드 변형)

Build Varients는 이름 그대로 빌드를 변형하기 위한 정보이다.

안드로이드 스튜디오에서 좌측 메뉴 중 Build Varients라는 메뉴가 있다. 

이 메뉴를 누르면 아래처럼 현재 빌드 변형 정보를 확인할 수 있다.

기본적으로 생성된 프로젝트는 이렇게 debug와 release라는 두 가지의 빌드 형태를 가지고 있다.

두 빌드는 디버그용과 출시용을 나누는 역할은 할 수 있지만, 같은 패키지명을 갖기에 함께 설치할 수 없다.

하지만, BuildTypes와 ProductFlavors를 수정하면 이 build varients들을 더 효과적으로 사용할 수 있다.

 

결과적으로 빌드 변형을 통해 얻게 되는 효과는 크게 두 가지이다.

 

1) 빌드를 단순 debug/release 외에도 목적에 맞게 다양하게 관리한다.

2) 각 빌드 별로 다른 패키지명을 갖게 하여 서로 다른 파일로 설치되게 한다.

 

BuildTypes와 ProductFlavors

BuildTypes와 ProductFlavors는 build varient를 구성하는 요소이다.

 

BuildType은 release/debug와 같이 빌드 설정을 관리할 때 사용되고,

ProductFlavors는 무료/유료와 같이 앱의 종류를 관리할 때 사용된다.

 

build varient는 BuildType과 ProductFlavors를 조합한 이름으로 생성된다.

예를 들어 BuildType에 release/debug를, ProductFlavors에 free/paid를 설정해 준다면 이렇게 4가지 빌드 변형을 사용할 수 있게 되는 것이다.

예상되듯이, freeDebug는 무료앱의 디버그 버전을 의미하며 나머지 빌드 변형도 각각에 맞는 의미를 갖는다.

 

 

BuildTypes

BuildTypes는 release/debug/inhouse 등의 빌드 설정을 관리할 때 사용된다.

앞서 언급했듯 release와 debug BuildType은 기본으로 사용할 수 있지만, 패키지명이 같아 함께 설치할 수 없다.

 

app단의 build.gradle 파일에 들어가 보면 이런 부분이 있다.

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

release에 대해서만 설정이 기입되어 있고, debug에 대한 추가 설정은 없다. 

    * 실제 릴리즈 빌드를 위해서는 release 빌드타입 설정 내부에 signing과 관련된 정보도 필요하다.

 

여기에 debug 속성을 추가해 주자.

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
    debug {
        applicationIdSuffix = ".debug"
    }
}

debug에 추가로 기입한 속성은 applicationIdSuffix = ".debug"이다.

이 속성을 추가해 줌으로서, debug빌드의 패키지명에는 끝에 .debug라는 이름이 붙는다.

이제 release 빌드와 패키지명이 다르기 때문에, 별도 앱으로 설치된다.

 

ProductFlavors

사실 정말 별도 앱으로 설치되어야 하는 경우는 디버그/릴리즈 빌드가 아니라, 무료/유료 앱일 것이다.

ProductFlavors는 BuildTypes에 비해서 더 복잡한 분류가 가능한데, 우선 아래는 가장 단순한 무료/유료 flavors이다.

flavorDimensions "version"
productFlavors {
    free {
        dimension = "version"
        applicationIdSuffix = ".free"
    }
    paid {
        dimension = "version"
        applicationIdSuffix = ".paid"
    }
}

이번에도 각 타입마다 applicationIdSuffix로 .paid와 .free를 달아 준 것을 확인할 수 있다.

 

여기에서 두 가지 의문이 생긴다.

Q. flavorDimensions와 dimension은 무엇일까?

Q. freeDebug앱의 패키지명에는 .free가 붙을까, .debug가 붙을까?

 

Q. flavorDimensions와 dimension은 무엇일까?

BuildTypes는 단순히 1차원적으로 타입을 정할 수 있다면, ProductFlavors는 다차원적(multi-dimensional)으로 빌드를 분류할 수 있다.

이 말만으로는 이해하기 어려우니 구체적인 예시를 들어 보겠다.

 

예시)

ProductFlavors로 무료/유료가 구분되어 있는 앱이 있다.

어느 날 이 앱을 한국/미국 버전으로 또다시 분리할 필요성이 생긴다.

이제 free-korea, free-us, paid-korea, paid-us의 네 가지(buildTypes 2가지를 곱하면 총 8가지)로 구분해야 하는데,

위의 4가지를 각각의 ProductFlavors로 만드는 것은 뭔가 아닌 것 같다.

 

이렇게 2가지 조건을 달리해야 하는 경우에 dimension을 잘 활용하면 2차원적인 분류가 가능하다.

위 시나리오에서 우리가 빌드 환경으로서 사용할 축은 두 가지이다.

 

1) 무료/유료 버전(version)

2) 지역(region)

 

이 각 축이 flavorDimension에 해당한다.

flavorDimensions "version", "region"
    productFlavors {
        korea {
            dimension = "region"
            applicationIdSuffix = ".korea"
        }
        us {
            dimension = "region"
            applicationIdSuffix = ".us"
        }
        free {
            dimension = "version"
            applicationIdSuffix = ".free"
        }
        paid {
            dimension = "version"
            applicationIdSuffix = ".paid"
        }
    }

위의 내용을 해석해보면, 우선 첫 줄에서 "version"과 "region"이라는 두 개의 축을 사용하겠다고 정의한다.

"region"이라는 dimension에는 korea와 us라는 두 개의 설정을 만들고,

"version"이라는 dimension에는 free와 paid라는 두 개의 상반된 설정를 만든다.

그리고 각각의 flavor에는 이전과 마찬가지로 applicationIdSuffix가 붙어 있다.

 

이렇게 2개의 dimension을 설정하면, 실제 build varient에는 (dimension1)(dimension2)와 같이 두 축이 합성되어 나타난다.

이 경우에는 (version)(region)이므로, 아래처럼 koreaFree, koreaPaid, koreaUs, koreaPaid가 되겠다.

물론 debug와 release는 이와 별개로 BuildType에 해당하므로 가장 마지막에 합성된다.

이제 한국/미국, 무료/유료, 디버그용/배포용 이라는 세 가지 조건을 모두 원하는 대로 설정해서 앱을 빌드할 수 있다.

 

Q. freeDebug앱의 패키지명에는 .free가 붙을까, .debug가 붙을까?

freeDebug, freeRease, paidDebug, paidRelease가 포함된 gradle 파일을 다시 보자.

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
    debug {
        applicationIdSuffix = ".debug"
    }
}

flavorDimensions "version"
productFlavors {
    free {
        applicationIdSuffix = ".free"
    }
    paid {
        applicationIdSuffix = ".paid"
    }
}

debug에도 .debug가 붙어 있고, free에도 .free가 붙어 있어서 둘중 하나가 첨부될 것이라고 생각할 수 있지만,

실제로 패키지명에는 두 가지가 모두 들어간다.

순서는 (기존 패키지명)(buildType)(productFlavors) 로, build varients에 나타나는 순서 그대로라고 보면 된다.

 

즉, 기존 패키지명이 com.example.someproject였다면,

freeDebug 빌드변형의 패키지명은 com.example.someproject.free.debug가 된다.

 

또한 위에서 flavorDimensions와 관련해서 두 개 이상의 dimension을 지정할 수도 있다고 했었는데, 이 경우도 살펴보자.

flavorDimensions "version", "region"

 

flavorDimensions가 정의되었던 순서는 "version", "region" 순서이다.

build varients의 이름에 붙는 flavor 부분은 flavorDimensions가 정의된 순서를 따른다.

version-region 순으로 정의했기 때문에, free-korea 순서로 이름이 정해진 것이다.

 

패키지명의 경우에도 같은 순서를 따른다.

따라서 이 경우 패키지명은 com.example.someproject.free.korea.debug가 되겠다.

 

반응형
Comments