빌드 변형을 사용하여 다양한 버전의 앱 만들기

1. 소개

최종 업데이트: 2022년 4월 14일

빌드 변형은 앱을 다양한 버전으로 만드는 데 유용합니다. 예를 들어 콘텐츠가 제한된 무료 버전의 앱과 더 많은 콘텐츠를 제공하는 유료 버전의 앱을 같이 빌드할 수 있습니다. 또한 API 수준이나 기타 기기 변형에 따라 서로 다른 기기를 타겟팅하는 다양한 버전의 앱을 빌드할 수도 있습니다.

이 Codelab에서는 1단원: Kotlin 기본사항에서 빌드한 Dice Roller 앱을 수정하여 'demo' 버전과 'full' 버전 두 가지를 만듭니다. 'full' 버전에는 주사위 굴리기 결과를 설명해주는 텍스트 상자가 있어 사용자가 이미지에만 의존해서 결과를 확인할 필요가 없습니다.

기본 요건

다음과 같은 준비가 되어 있어야 합니다.

  • Android 기본사항 학습 과정 1~4 완료. 필요한 Codelab을 실행하려면 1단원: Kotlin 기본사항 개발자 과정을 참고하세요.
  • Android 빌드 시스템에 관한 일반적인 이해. 기본 구성요소를 숙지하려면 빌드 개요를 검토하세요.

학습할 내용

  • 빌드 변형 정의
  • 소스 세트 정의
  • 빌드 변형과 소스 세트를 사용하여 다양한 버전의 앱을 빌드하는 방법
  • 앱 변형에 고유한 애플리케이션 ID를 부여하는 방법

빌드할 항목

이 Codelab에서는 1단원: Kotlin 기본사항의 학습 과정을 통해 빌드한 DiceRoller 앱으로 시작합니다. DiceRoller 앱에는 주사위 그림과 그 아래에 ROLL 버튼이 있습니다. 사용자가 ROLL을 클릭하면 주사위가 굴러가고 그 결과에 따라 그림이 변경됩니다.

추가 프로젝트 파일을 만들고 코드를 추가하여 다음을 실행합니다.

  • 'demo' 제품 버전과 'full' 제품 버전의 앱을 만듭니다.
  • 제품 버전에 상응하는 'demo' 소스 세트와 'full' 소스 세트를 만듭니다.
  • 'full' 버전 앱의 레이아웃에 상자를 추가합니다.
  • 사용자가 ROLL을 클릭할 때 주사위 굴리기 결과가 표시되도록 'full' 버전 상자를 프로그래밍합니다.
  • 'demo' 및 'full' 앱 버전의 앱 제목을 맞춤설정합니다.
  • 'demo' 및 'full' 앱 버전에 고유한 애플리케이션 ID를 부여합니다.

앱의 full 버전은 다음과 같이 표시됩니다.

동적 상자가 있는 DiceRoller 앱

필요한 항목

2. 환경 설정

코드 가져오기

1단원: Kotlin 기본사항에서 완성된 DiceRoller 앱이 없다면 GitHub에서 앱 코드를 다운로드합니다.

Android 스튜디오에서 앱 코드를 다운로드하고 열려면 다음 단계를 따르세요.

  1. android-basics-kotlin-dice-roller-with-images-app-solution GitHub 저장소 홈페이지에서 Code > Download ZIP을 클릭합니다.
  2. ZIP 파일이 다운로드되면 Android 스튜디오에서 프로젝트를 열고 File > Open을 클릭합니다. Empty Activity를 시작하거나 메시지가 표시되면 이전 프로젝트를 열 수 있습니다. 여기서는 다운로드한 프로젝트를 열겠습니다.
  3. ZIP 파일을 다운로드한 위치(Downloads 폴더일 수 있음)로 이동하여 선택하고 Open을 클릭합니다.

Project 뷰 사용

빌드 변형으로 작업할 때 빌드 변형에서 여러 변형의 디렉터리를 모두 확인하려면 Project 뷰에서 프로젝트 파일로 작업해야 합니다. 이렇게 하려면 Android 스튜디오에서 Project 창을 열고 view type 메뉴(기본적으로 Android 뷰로 설정됨)를 클릭한 후 Project 뷰를 선택합니다.

3. 빌드 변형 이해

빌드 변형은 제품 버전빌드 유형이 다양하게 조합된 결과입니다. 제품 버전은 좀 더 사용자 대상의 속성, 빌드 유형은 좀 더 개발자 대상의 속성으로 생각할 수 있습니다. 개발자가 실제로 빌드 변형을 직접 구성하지는 않습니다. 그보다는 제품 버전 세트와 빌드 유형 세트를 구성함에 따라 빌드 변형이 결정됩니다.

특히 빌드 변형은 모든 조합의 제품 버전과 빌드 유형을 나타내며 그에 따라 <product-flavor><build-type>으로 이름이 지정됩니다. 예를 들어 빌드 유형이 debug, release이고 제품 버전이 demo, full이라면 이를 기반으로 한 빌드 변형은 다음과 같습니다.

  • demoDebug
  • demoRelease
  • fullDebug
  • fullRelease

이제 DiceRoller 앱의 제품 버전과 빌드 유형을 구성해 보겠습니다.

4. 제품 버전 구성

제품 버전은 일반적으로 사용자에게 제공되는 앱 버전을 나타낸다는 의미에서 좀 더 사용자 대상의 앱 속성입니다. 앱의 demo 버전과 full 버전을 만들려면 두 제품 버전을 추가하고 버전 차원에 할당해야 합니다. 제품 버전을 추가하려면 앱 수준 build.gradle 파일(Project 뷰에서 app > build.gradle)을 열고 이 코드를 android {} 블록에 붙여넣습니다.

flavorDimensions "app_type"
productFlavors {
   demo {
       dimension "app_type"
         }
   full {
       dimension "app_type"
   }
}

이 코드는 다음 작업을 실행합니다.

  • app_type이라는 버전 차원을 만듭니다.
  • demo {}full {} 블록으로 표시되는 두 가지 제품 버전을 만듭니다.
  • 두 제품 버전을 app_type 차원에 할당합니다(버전 차원이 하나만 있는 경우 선택사항임).

이 코드는 제품 버전을 정의하는 데 필요한 기본 코드입니다. 이 Codelab의 후반부에서는 몇 가지 추가 옵션을 사용하게 됩니다.

5. 빌드 유형 구성

빌드 유형은 일반적으로 개발 단계(예: 디버그, 베타, 출시)를 나타낸다는 의미에서 좀 더 개발자 대상의 앱 속성입니다. Android 스튜디오에서는 debug 빌드 유형과 release 빌드 유형 두 가지를 자동으로 구성합니다. debug 빌드 유형은 디버깅용이고 release 빌드 유형은 배포용입니다.

앱 수준 build.gradle 파일에서 buildTypes {} 블록을 수정하여 빌드 유형을 만들고 그 구성을 수정할 수 있습니다. 기본 buildTypes {} 블록은 다음과 같습니다.

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

release 빌드 유형의 기본 구성을 확인할 수 있습니다(이 Codelab에서는 minifyEnabled 또는 proguardFiles 속성을 다루지 않음). debug 빌드 유형은 기본적으로 빌드 구성 파일에 표시되지 않지만 debug {} 블록을 추가하여 특정 설정을 추가하거나 변경할 수 있습니다. 여기서는 기본 구성만으로 충분하므로 그대로 둡니다.

6. Build Variants 도구 창 사용

두 가지 제품 버전과 두 가지 빌드 유형이 있으므로 이제 어떤 빌드 변형이 만들어지는지 살펴보겠습니다. Android 스튜디오에서 새 빌드 변형을 보려면 다음 단계를 따르세요.

  1. 툴바에서 Sync Project with Gradle Files 4e7fbf18152549d8.png를 클릭합니다. 빌드 구성 파일을 변경할 때마다 스튜디오에서는 새로운 빌드 구성을 저장하고 빌드 오류를 확인할 수 있도록 파일을 동기화하라는 메시지를 표시합니다.
  2. Build > Select Build Variant(또는 View > Tool Windows > Build Variants)를 클릭하여 Build Variants 창을 표시합니다.
  3. Active Build Variant 열에서 demoDebug를 클릭하여 모든 빌드 변형(demoDebug, demoRelease, FullDebug, FullRelease)이 포함된 메뉴를 엽니다. 실행하고 테스트할 다양한 빌드 변형을 선택하는 데 이 메뉴를 사용합니다.

Active Build Variant 메뉴가 표시된 Build Variants 도구 창

demoDebugfullDebug 변형을 실행합니다(release 빌드 유형에 따른 변형은 실행하는 데 더 많은 설정이 필요하므로 이 Codelab에서는 다루지 않음). 지금까지는 demoDebugfullDebug 변형을 사용자 관점에서 구별할 수 없습니다.

7. 여러 변형을 위한 다양한 기능 만들기

이제 demo 및 full 앱 버전이 있으므로 full 버전에 몇 가지 기능을 추가해 보겠습니다.

소스 세트를 사용하여 프리미엄 기능 추가

full 제품 버전의 경우 주사위 굴리기의 결과를 보여주는 상자를 추가해 보겠습니다. 그러면 사용자는 주사위 이미지에만 의존해서 결과를 확인할 필요가 없습니다. 이 프리미엄 기능을 추가하려면 소스 세트를 사용합니다. 소스 세트는 특정 빌드 유형과 제품 버전, 빌드 변형에 관한 콘텐츠가 포함된 디렉터리입니다. 기본 main 소스 세트(app > src > main)에는 모든 빌드 변형 간에 공유할 콘텐츠가 포함되어 있습니다. 이 기본 콘텐츠는 다른 소스 세트의 콘텐츠로 재정의할 수 있습니다.

main 소스 세트에 있는 항목을 재정의하고 추가해야 하는 소스 세트를 결정하는 방식은 변경하려는 항목에 따라 다릅니다.

레이아웃이나 이미지(main > res에 있는 항목)와 같은 리소스를 변경하려면 다음 일반 단계를 따르세요.

  1. 변경하려는 제품 버전의 소스 세트 또는 디렉터리를 만듭니다. 다음 섹션에서는 이 소스 세트를 만드는 위치와 방법을 알아봅니다.
  2. 변경하려는 리소스 파일을 새 소스 세트에 붙여넣은 다음 업데이트합니다. Android Gradle 플러그인(AGP)이 새 소스 세트에 종속된 빌드 변형을 빌드할 때 main의 리소스 코드를 새 소스 세트의 리소스 코드로 재정의합니다.

자바 또는 Kotlin 클래스의 동작(main > java에 있는 항목)을 재정의하려면 다음 일반 단계를 따르세요.

  1. 변경하려는 제품 버전 및 동일한 버전 차원에 있는 다른 모든 제품 버전의 소스 세트 또는 디렉터리를 만듭니다.
  2. 변경하려는 파일을 모든 제품 버전 소스 세트에 붙여넣은 후 변경하려는 사본을 수정합니다.
  3. main 소스 세트에서 원본 파일을 삭제합니다.

full 버전 앱에 동적 상자를 추가하려면 프리미엄 기능을 다음 두 가지 기본 수정사항으로 생각하는 것이 좋습니다.

  • 레이아웃 맞춤설정: activity_main.xml 파일을 수정하여 상자를 추가합니다.
  • 앱 동작 맞춤설정: MainActivity.kt 파일을 수정하여 주사위 굴리기에 따라 상자에 표시되는 내용을 변경합니다.

다음 섹션에서는 소스 세트를 만드는 위치와 방법을 알아봅니다.

새 소스 세트를 만들 위치 결정

Android Gradle 플러그인(AGP)은 각 빌드 유형과 제품 버전, 빌드 변형에 관한 파일의 구성 방법을 보여줍니다. MainActivity.kt 파일의 변경사항이 포함된 full 제품 버전에 프리미엄 기능을 추가하려면 full 버전과 demo 버전에 모두 소스 세트를 만듭니다. 이러한 소스 세트를 만들 위치를 확인하려면 Android 스튜디오에서 다음 단계를 따르세요.

  1. IDE 창에서 Gradle을 클릭합니다.
  2. MyApplication > Tasks > android로 이동하여 sourceSets를 더블클릭합니다. Tasks 폴더가 표시되지 않으면 File > Settings > Experimental을 클릭하고 Do not build Gradle task list during Gradle sync(macOS는 Android Studio > Preferences > Experimental)를 선택 해제하여 동기화하는 동안 Gradle이 작업 목록을 빌드하도록 합니다. Gradle에서 작업을 실행하면 Run 창에 출력이 표시됩니다.
  3. 표시된 내용이 다음과 같이 텍스트 모드가 아닌 경우 Run 창에서 Toggle view 82487fd4e011f105.png를 클릭합니다.

Run 창에 다음과 같이 출력됩니다.

------------------------------------------------------------
Project ':app'
------------------------------------------------------------

...

debug
-----
Compile configuration: debugCompile
build.gradle name: android.sourceSets.debug
Java sources: [app/src/debug/java]
Kotlin sources: [app/src/debug/kotlin, app/src/debug/java]
Manifest file: app/src/debug/AndroidManifest.xml
Android resources: [app/src/debug/res]
Assets: [app/src/debug/assets]
AIDL sources: [app/src/debug/aidl]
RenderScript sources: [app/src/debug/rs]
JNI sources: [app/src/debug/jni]
JNI libraries: [app/src/debug/jniLibs]
Java-style resources: [app/src/debug/resources]

...

full
----
Compile configuration: fullCompile
build.gradle name: android.sourceSets.full
Java sources: [app/src/full/java]
Kotlin sources: [app/src/full/kotlin, app/src/full/java]
Manifest file: app/src/full/AndroidManifest.xml
Android resources: [app/src/full/res]
Assets: [app/src/full/assets]
AIDL sources: [app/src/full/aidl]
RenderScript sources: [app/src/full/rs]
JNI sources: [app/src/full/jni]
JNI libraries: [app/src/full/jniLibs]
Java-style resources: [app/src/full/resources]

'debug' 아래의 파일 경로 목록은 AGP가 기본적으로 'debug' 제품 버전의 앱 코드와 리소스를 찾는 위치를 설명합니다. 마찬가지로 'full' 아래의 파일 경로 목록은 AGP가 기본적으로 'full' 제품 버전의 콘텐츠를 찾는 위치를 설명합니다.

'자바 소스'(자바 및 Kotlin 클래스와 같은 파일의 경우) 및 'Android 리소스'(레이아웃 및 이미지와 같은 파일의 경우) 파일 경로를 기록해 둡니다. 이제 새 소스 세트를 만들 위치를 알았으므로 소스 세트를 만들고 프리미엄 기능 코드를 추가하세요.

full 버전의 레이아웃 맞춤설정

full 버전 앱에 상자를 추가하려면 다음 단계를 따르세요.

첫째, full 소스 세트와 자바 리소스 디렉터리를 만듭니다.

  1. Project 창을 열고 Project 뷰를 선택합니다.
  2. DiceRoller/app/src/ 디렉터리로 이동합니다.
  3. src 디렉터리를 마우스 오른쪽 버튼으로 클릭하고 New > Directory를 선택합니다.
  4. Gradle Source Sets 아래의 메뉴에서 full/resources를 선택하고 Enter를 누릅니다.

둘째, main 소스 세트의 activity_main.xml 파일을 full 소스 세트에 붙여넣습니다.

  1. DiceRoller/app/src/main/res/로 이동합니다.
  2. activity_main.xml 파일을 마우스 오른쪽 버튼으로 클릭하고 Copy를 클릭합니다.
  3. DiceRoller/app/src/full/res/로 이동합니다.
  4. res 디렉터리를 마우스 오른쪽 버튼으로 클릭하고 Paste를 클릭합니다.

셋째, full 버전의 앱에 상자를 추가하려면 이 코드를 full 소스 세트의 activity_main.xml 파일에 추가합니다.

<TextView
    android:id="@+id/resultTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="16sp"
    android:text="Result"
    app:layout_constraintBottom_toTopOf="@+id/button"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/imageView" />

앱의 fullDebugdemoDebug 빌드 변형을 실행합니다(Build Variants 도구 창을 사용하여 실행할 빌드 변형을 선택한 다음 Run 클릭). fullDebug 변형에만 새 상자가 표시됩니다. 이 상자는 아직 아무것도 하지 않으므로 주사위 굴리기에 따라 변경되도록 프로그래밍해 보겠습니다.

'Result'가 자리표시자로 표시된 상자가 있는 DiceRoller 앱

full 버전의 동작 맞춤설정

full 버전 앱의 경우 상자에는 주사위 굴리기의 결과가 단어로 표시되어야 합니다. 이 동작을 프로그래밍하려면 다음 단계를 따르세요.

첫째, full 소스 세트와 자바 소스 디렉터리를 만듭니다.

  1. Project 뷰의 Project 창에서 DiceRoller/app/src/full 디렉터리로 이동합니다.
  2. full 디렉터리를 마우스 오른쪽 버튼으로 클릭하고 New > Directory를 선택합니다.
  3. Gradle Source Sets 메뉴에서 java를 선택하고 Enter를 누릅니다.

둘째, debug 소스 세트와 자바 소스 디렉터리를 만듭니다.

  1. Project 뷰의 Project 창에서 DiceRoller/app/src 디렉터리로 이동합니다.
  2. src 디렉터리를 마우스 오른쪽 버튼으로 클릭하고 New > Directory를 선택합니다.
  3. Gradle Source Sets 메뉴에서 debug/java를 선택하고 Enter를 누릅니다.

셋째, DiceRoller/app/src/main/java 디렉터리로 이동합니다.

  1. MainActivity.kt 파일을 full/javadebug/java 디렉터리에 모두 붙여넣습니다.
  2. 기본 소스 세트에서 MainActivity.kt 파일을 포함한 java 디렉터리를 삭제합니다. java 디렉터리를 마우스 오른쪽 버튼으로 클릭하고 Delete를 클릭합니다.
  3. 전체 소스 세트 MainActivity.kt 파일에서 다음 코드를 rollDice() 메서드에 추가합니다.
// Update the result text view
val resultTextView: TextView = findViewById(R.id.resultTextView)
resultTextView.text = when (diceRoll) {
    1 -> "One"
    2 -> "Two"
    3 -> "Three"
    4 -> "Four"
    5 -> "Five"
    else -> "Six"
}

fullDebugdemoDebug 빌드 변형을 다시 실행합니다. full 버전의 상자에는 주사위 굴리기 결과가 포함되어야 합니다.

동적 상자가 있는 DiceRoller 앱

앱 제목 변경

명확성을 위해 앱 제목에 사용 중인 앱 버전을 지정해 보겠습니다. 이러한 유형의 변경은 실제로 소스 세트 없이 실행할 수 있습니다. 앱 제목은 AndroidManifest.xml 파일(app > manifests > AndroidManifest.xml)의 label 속성으로 정의합니다. 실행되는 변형에 따라 변경되는 label 값을 가져오려면 AndroidManifest.xml 파일을 열고 라벨 줄을 다음과 같이 변경합니다.

android:label="${appLabel}"

이렇게 하면 앱 제목으로 appLabel 변수가 할당됩니다.

이제 appLabel 값을 설정하거나 demo 버전 앱의 제목을 변경하려면 manifestPlaceholders 줄을 이전에 만든 demo {} 블록에 추가합니다.

demo {
   dimension "version"
   manifestPlaceholders = [appLabel: "Dice Roller - Demo"]
   applicationIdSuffix ".demo"
}

마찬가지로 full 버전 앱의 제목을 변경하려면 full {} 블록에도 manifestPlaceholders 줄을 추가합니다.

full {
   dimension "version"
   manifestPlaceholders = [appLabel: "Dice Roller - Full"]
   applicationIdSuffix ".full"
}

이제 demoDebugfullDebug 변형을 다시 실행합니다. 이제 빌드 변형마다 다른 제목이 표시됩니다.

동적 상자가 있는 완성된 DiceRoller 앱

8. 빌드 변형에 고유한 애플리케이션 ID 부여

앱의 APK 또는 AAB를 빌드할 때 빌드 도구는 앱 수준 build.gradle 파일의 defaultConfig {} 블록에 정의된 애플리케이션 ID로 앱에 태그를 지정합니다(아래 참고). 그러나 Google Play 스토어에 별도의 목록으로 표시되도록 다양한 버전의 앱(예: 'demo' 또는 'full' 버전)을 만들려면 각 버전에 다른 애플리케이션 ID를 부여해야 합니다. productFlavors {} 블록 내부의 각 버전에 applicationId 속성을 재정의하거나, 아래와 같이 applicationIdSuffix를 사용하여 기본 애플리케이션 ID에 세그먼트를 추가할 수 있습니다.

defaultConfig {
   applicationId "com.example.diceroller"
   ...
}

flavorDimensions "version"
productFlavors {
   demo {
 dimension "version"
       manifestPlaceholders = [appLabel: "Dice Roller - Demo"]
         applicationIdSuffix ".demo"
   }
   full {
       dimension "version"
       manifestPlaceholders = [appLabel: "Dice Roller - Full"]
         applicationIdSuffix ".full"
   }
}

9. 축하합니다

축하합니다. 빌드 변형을 사용하여 DiceRoller 앱의 두 가지 버전을 빌드했습니다.

제품 버전과 빌드 유형을 구성하여 빌드 변형을 만들었습니다. 소스 세트를 사용하여 'full' 앱 버전에 프리미엄 기능을 추가했습니다. Play 스토어에서 별도의 앱으로 간주되도록 각 빌드 변형에 고유한 애플리케이션 ID를 부여하는 방법을 알아봤습니다.

지금까지 다양한 사용자 그룹에 더 나은 서비스를 제공하기 위해 여러 버전의 앱을 만드는 데 필요한 기본적인 단계를 알아봤습니다.

다음 단계

참조 문서