본문 바로가기

안드로이드/멀티 모듈

[안드로이드 멀티 모듈] 6. AndroidApplicationComposeConventionPlugin 만들기


지난 포스팅에서는 app 모듈의 컨벤션 플러그인 AndroidApplicationConventionPlugin을 만들었습니다. 최근 안드로이드에서는 기존의 XML방식에서 선언형 UI 프로그래밍인 Compose 방식으로 많이 전환되고 있는데, Compose로 개발을 하기 위해서 빌드 관련 코드를 추가해야 합니다. 이번 포스팅에서는 Compose Application 모듈을 위한 AndroidApplicationComposeConventionPlugin을 만들겠습니다.

이번 포스팅까지 진행한 build-logic 모듈의 파일 및 패키지 구조
이번 포스팅까지 진행한 build-logic 모듈의 파일 및 패키지 구조

1. AndroidCompose 유틸 함수 만들기

지난 포스팅과 마찬가지로 여러 컨벤션 플러그인에서 공통으로 사용할 수 있는 AndroidCompose 유틸 함수를 만들겠습니다. 해당 함수에서는 안드로이드 Compose 관련 빌드 로직을 정의합니다. 그리고 Compose 관련 의존성을 추가할 수도 있습니다.

// AndroidCompose.kt
internal fun Project.configureAndroidCompose(
    commonExtension: CommonExtension<*, *, *, *, *, *>
) {
    commonExtension.run {
        buildFeatures {
            compose = true
        }

        composeOptions {
            kotlinCompilerExtensionVersion = libs.findVersion("composeCompiler").get().toString()
        }

        dependencies {
            val bom = libs.findLibrary("androidx.compose.bom").get()
            add("implementation", platform(bom))
            add("androidTestImplementation", platform(bom))
            add("debugImplementation", libs.findLibrary("androidx.ui.tooling.preview").get())
        }
    }
}


Compose 관련 의존성은 compose-bom으로 관리되는 반면, Compose Compiler는 composeOptions 블록에 따로 명시를 해야 합니다. Kotlin 버전마다 Compose Compiler 버전이 상이하므로 주의해야 합니다. 여기서는 Kotlin 1.9.22 버전을 사용하기 때문에 Compose Compiler의 버전은 1.5.9로 적용해야 합니다.

최근 Kotlin 2.0 버전이 출시됐는데, Kotlin 2.0 이상에서는 코틀린 버전별로 Compose Compiler를 따로 관리할 필요가 없습니다.

2. AndroidApplicationComposeConventionPlugin 만들기

지난 포스팅에서 AndroidApplicationConventionPlugin을 만들었기 때문에 간단하게 구성할 수 있습니다. 아래 코드처럼 플러그인을 적용할 수 있는 pluginManager를 통해서 AndroidApplicationConventionPlugin을 적용하고, 위의 1번 과정에서 만든 유틸 함수를 호출하면 완성입니다.

// AndroidApplicationComposeConventionPlugin.kt
class AndroidApplicationComposeConventionPlugin: Plugin<Project> {
    override fun apply(target: Project) {
        target.run {
            pluginManager.apply("multi.module.android.application")

            val extension = extensions.getByType<ApplicationExtension>()
            configureAndroidCompose(extension)
        }
    }
}

3. AndroidApplicationComposeConventionPlugin 적용하기

Gradle에게 특정 id로 컨벤션 플러그인을 인식할 수 있도록 아래처럼 libs.versions.toml 파일에 id를 정의하고 build-logic 모듈에 위에서 만든 컨벤션 플러그인을 등록합니다. implementationClass에는 Class 이름을 적으면 됩니다.

// libs.versions.toml
...

# Custom Convention Plugin
multi-module-android-application = { id = "multi.module.android.application", version = "unspecified"}
multi-module-android-application-compose = { id = "multi.module.android.application.compose", version = "unspecified"}
// build.gradle.kts (Module :build-logic:convention)
...

gradlePlugin {
   plugins {
      // 이전 포스팅에서 등록한 컨벤션 플러그인
      register("androidApplication") {
         id = "multi.module.android.application"
         implementationClass = "AndroidApplicationConventionPlugin"
      }
      
      // 이번 포스팅에서 등록한 컨벤션 플러그인
      register("androidApplicationCompose") {
         id = "multi.module.android.application.compose"
         implementationClass = "AndroidApplicationComposeConventionPlugin"
      }
   }
}


마지막으로 build.gradle.kts (:app) 모듈에서 AndroidApplicationComposeConventionPlugin을 적용하고 compose 관련된 코드를 제거하면 됩니다. 아래의 코드를 보면 처음과는 다르게 대부분의 빌드 관련 코드가 컨벤션 플러그인에서 관리되는 모습을 볼 수 있습니다.

// build.gradle.kts (:app)
plugins {
    // 컨벤션 플러그인 적용
    alias(libs.plugins.multi.module.android.application.compose)
}

android {
    namespace = "com.multi.module.template"

    defaultConfig {
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        vectorDrawables {
            useSupportLibrary = true
        }
    }

    packaging {
        resources {
            excludes += "/META-INF/{AL2.0,LGPL2.1}"
        }
    }
}

dependencies {
    ...
}

4. 정리

이번 포스팅에서는 Compose Application 모듈을 위한 AndroidApplicatonComposeConventionPlugin을 만들었습니다.
buildTypes, buildFeature 등의 모든 공통 코드를 컨벤션 플러그인에서 관리할 수 있게 되었습니다.

지금까지는 Application 모듈과 관련된 컨벤션 플러그인을 만들었는데, 다음 포스팅에서는 AndroidLibrary 모듈과 관련된 컨벤션 플러그인을 만들 예정입니다. 기본적인 구조는 똑같고, 컨벤션 플러그인의 유틸함수도 만들어놓은 상태이기 때문에 추가되는 컨벤션 플러그인들은 쉽게 만들 수 있습니다.

이번 포스팅의 결과물은 아래 Github Repository의 6-AndroidApplicationComposeConventionPlugin 브랜치를 확인하시면 됩니다.

 

GitHub - taein8935/multi-module-template-aos

Contribute to taein8935/multi-module-template-aos development by creating an account on GitHub.

github.com