Android / Kotlin / Programming

configの一元管理をする方法 – Android Kotlin

はじめに

この記事はMulti-Module(マルチモジュール)実装シリーズです。
前回はGradleでdependenciesを一元管理する方法を紹介しました。
今回はその続きとなる、plugins{}やandroid{}などのconfigを一元管理する方法をご紹介します。

新たにクラスを作り、そのクラス内でconfigの宣言を行い、gradleではそのクラスを適用することで一元管理を可能にしています。
デメリットとしては、appのgradleにはそのクラスを適用することができません。
ちなみにNowInAndroidでは別の方法でやっており、こちらのほうがより見やすいと思います。

一元管理の方法

こちらで作成したbuildSrcにあるkotlinフォルダ内に「MainGradlePlugin」クラスを作ります。
※クラス名は任意の値です


import com.android.build.gradle.LibraryExtension
import org.gradle.api.JavaVersion
import org.gradle.api.Plugin
import org.gradle.api.Project

class MainGradlePlugin: Plugin<Project> {
    override fun apply(project: Project) {
        applyPlugins(project)
        setProjectConfig(project)
    }

    private fun applyPlugins(project: Project) {
        project.apply {
            plugin("org.jetbrains.kotlin.android")
        }
    }

    private fun setProjectConfig(project: Project) {
        project.android().apply {
            compileSdk = ProjectConfig.compileSdk

            defaultConfig {
                minSdk = ProjectConfig.minSdk
                testInstrumentationRunner = ProjectConfig.testInstrumentationRunner
                vectorDrawables {
                    useSupportLibrary = true
                }
            }

            buildTypes {
                release {
                    isMinifyEnabled = true
                    proguardFiles(
                        getDefaultProguardFile("proguard-android-optimize.txt"),
                        "proguard-rules.pro"
                    )
                }
            }

            compileOptions {
                sourceCompatibility = JavaVersion.VERSION_18
                targetCompatibility = JavaVersion.VERSION_18
            }

            buildFeatures {
                compose = true
            }

            composeOptions {
                kotlinCompilerExtensionVersion = ProjectConfig.kotlinCompilerExtensionVersion
            }

            packaging {
                resources {
                    excludes += ProjectConfig.metaInfoPath
                }
            }
        }
    }

    private fun Project.android(): LibraryExtension {
        return extensions.getByType(LibraryExtension::class.java)
    }
}

MainGradlePlugin.ktをこのように書き換えます。


同じように、buildSrcにあるkotlinフォルダ内に「ProjectConfig」オブジェクトを作ります。
※オブジェクト名は任意の値です


object ProjectConfig {
    const val appId = "XXXXXX" // ご自身のものに変更してください
    const val minSdk = 29
    const val compileSdk = 33
    const val targetSdk = 33
    const val versionCode = 1
    const val versionName = "1.0"
    const val testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    const val kotlinCompilerExtensionVersion = "1.4.3"
    const val jvmTarget = "18"
    const val metaInfoPath = "/META-INF/{AL2.0,LGPL2.1}"
}

ProjectConfig.ktをこのように書き換えます。


import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    `kotlin-dsl`
}

repositories {
    google()
    mavenCentral()
}

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10")
    implementation("com.android.tools.build:gradle:8.1.3")
}

val compileKotlin: KotlinCompile by tasks
compileKotlin.kotlinOptions {
    jvmTarget = "18"
}

buildSrcにある「build.gradle.kts」をこのように書き換えます。


plugins {
    id("com.android.library")
}

apply<MainGradlePlugin>()

android {
    namespace = "com.XXXXXX.module_name" // ご自身のものに書き換えてください

    defaultConfig {
        consumerProguardFiles("consumer-rules.pro")
    }
}

dependencies {

    implementation("androidx.core:core-ktx:1.9.0")
    implementation("androidx.appcompat:appcompat:1.6.1")
    implementation("com.google.android.material:material:1.8.0")
    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.1.5")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")

    compose()
}

こちらで作成したgroupのように、モジュールの「build.gradle.kts」をこのように書き換えます。


plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
}

android {
    namespace = "com.XXXXXX.YYYYYY" // ご自身のものに書き換えてください
    compileSdk = ProjectConfig.compileSdk

    defaultConfig {
        applicationId = ProjectConfig.appId
        minSdk = ProjectConfig.minSdk
        targetSdk = ProjectConfig.targetSdk
        versionCode = ProjectConfig.versionCode
        versionName = ProjectConfig.versionName

        testInstrumentationRunner = ProjectConfig.testInstrumentationRunner
        vectorDrawables {
            useSupportLibrary = true
        }
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_18
        targetCompatibility = JavaVersion.VERSION_18
    }
    kotlinOptions {
        jvmTarget = ProjectConfig.jvmTarget
    }
    buildFeatures {
        compose = true
    }
    composeOptions {
        kotlinCompilerExtensionVersion = ProjectConfig.kotlinCompilerExtensionVersion
    }
    packaging {
        resources {
            excludes += ProjectConfig.metaInfoPath
        }
    }
}

dependencies {

    implementation("androidx.core:core-ktx:1.9.0")
    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
    activityCompose()
    compose()
    group()
    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.1.5")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}

appにある「build.gradle.kts」をこのように書き換えます。
これで同期と「Run app」が問題なくできると思います。

おわりに

次回はNowInAndroidで使用している方法を紹介しようと思います。
多分こちらのほうがすっきりすると思われます。

参考

How to Build a Custom Gradle Plugin to Share Project Config – Multi-Module Architecture (YouTube)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です