Android

Android Flavor(Product Flavor)

chattymin 2025. 3. 30. 17:44
728x90

 

Android Product Flavor란?

하나의 코드베이스에서 서로 다른 버전의 앱을 만들기 위한 기능이다.

우리가 사용하던 debug, relaease를 커스텀으로 만들 수 있다고 생각하면 된다.

 

언제 사용할까?

  • 앱 브랜드가 다를 때 (같은 기능인데 로고, 테마만 다르게)
  • 환경별 분리 (dev, staging, prod)
  • 지역별 버전 (KR, JP, US)
  • 유료 / 무료 앱

대충 이렇게 기능은 대부분 같지만 일부만 다를 경우에 구분해서 사용하고자 할 때 Flavor를 이용한다.

나는 sdk의 버전별로 샘플 앱을 만들어야 할 때 flavor를 버전으로 설정하여 기능을 공유하는 여러 앱을 만들 때 사용했다.

 

 

어떻게 쓸까?

android {
    ...
    flavorDimensions "version"
    productFlavors {
        v5 {
            dimension "version"
            applicationIdSuffix ".v5"
            versionNameSuffix "-v5"
        }

        v6 {
            dimension "version"
            applicationIdSuffix ".v6"
            versionNameSuffix "-v6"
        }
    }
}

dependencies {
    // 공통으로 사용하는 의존성
    implementation 'androidx.core:core-ktx:1.12.0'

    
    v5Implementation 'com.google.android:test:5.0.0' // v5
    v6Implementation 'com.google.android:test:6.0.0' // v6
}

 

flavorDimensions을 통해 각 flavor를 나누는 기준을 만들어 준다.

 

그 후 productFlavors에서 해당하는 dimension으로 구분할 경우들을 만들어 주면 된다.

나의 경우 version으로 나누었고, v5와 v6를 만들었다.

 

 

 

그렇게 되면 이렇게 자동으로 Build Variants가 만들어 진다.

 

각 flavor에 맞게 버전 정보 등을 넣을 수도 있고, 정보들을 공유하되 Suffix를 붙이는 방법도 있다.

 

현재 내가 작성해둔 내용을 바탕으로 예시를 들어보자.

defaultConfig {
    applicationId "com.example.test"
    versionCode 13
    versionName "1.3.0"
}

 

 

이 값을 이용해 위에 나타낸 flavor를 적용시키면 아래처럼 된다.

Flavor applicationId versionName
v5 com.example.test.v5 1.3.0-v5
v6 com.example.test.v6 1.3.0-v6

 

 

또한 해당하는 Flavor에만 특정 라이브러리를 implement하는 것도 가능하다.

 

[flavorName][ConfigurationType] 이러한 규칙에 따라 작성하면 된다.

ex)

  • v5Implementation
  • v5Api
  • v5DebugImplementation
  • v5ReleaseRuntimeOnly

 

해당 기능을 사용한다면 하나의 라이브러리, SDK 를 flavor에 따라 다른 버전을 사용할 수 도 있다.

또한 특정 flavor에만 해금되는 기능이라거나 다른 Const값을 자동으로 적용하게 하는 등의 작업을 할 수 있다.

 

 

 

이처럼 패키지 구조가 만들어지고, 원하는 내용을 넣으며 사용할 수 있다.

단, 인식이 가능한 것이지 자동으로 패키지가 만들어지는 것은 아니니 패키지 정도는 직접 만들자.

 

 

예시로 알아보자.

해당 기능을 사용할 당시 Application class에서 flavor에 맞게 초기화 해야하는 코드들이 필요했다.

그래서 해당 기능들을 사용하기 위해 abstract class BaseApp을 구현하고, flavor 내부에서 이를 상속받아 구현한 class App을 만들었다.

abstract class BaseApp : Application() {
    override fun onCreate() {
        super.onCreate()

				commonFunction()
        initVersionLibrary()
    }
    
    private fun commonFunction() {
		    // Something Do
    }

    abstract fun initVersionLibrary()
    
    fun initSomething(code: String) {
		    Log.e("test", "this is $code")
    }

    companion object {
        const val V5_TEST = "v5"
        const val V6_TEST = "v6"
    }
}
// Flavor v5
class App : BaseApp() {
    override fun onCreate() {
        super.onCreate()

        initSomething(V5_TEST)
    }

    override fun initVersionLibrary() {
        // Something Do
    }
}
// Flavor v6
class App : BaseApp() {
    override fun onCreate() {
        super.onCreate()

        initSomething(V6_TEST)
    }

    override fun initVersionLibrary() {
        // Something Do
    }
}

이런식으로도 사용이 가능하다.

이 외에도 Activity를 활용해도 되고, 다른 것들을 활용해도 된다.

 

 

 

더욱 다양한 기능을 쓰고 싶다면 공식문서를 보길 추천한다.

https://developer.android.com/build/build-variants?hl=ko

 

빌드 변형 구성  |  Android Studio  |  Android Developers

빌드 변형을 구성하여 단일 프로젝트에서 여러 버전의 앱을 만드는 방법을 알아보세요.

developer.android.com

 

728x90