Android Coden
Android 4 min lesen

Build-Logik organisieren: Convention Plugins in Android-Projekten

Convention Plugins bündeln wiederholte Gradle-Konfiguration zentral. So bleiben auch große Multi-Modul-Projekte konsistent und wartbar.

Sobald ein Android-Projekt über ein einzelnes Modul hinauswächst, wiederholt sich Gradle-Konfiguration auf unangenehme Weise: Compiler-Optionen, Lint-Regeln, AGP-Versionen und Compose-Einstellungen tauchen in jeder build.gradle.kts-Datei nahezu identisch auf. Build-Logik-Organisation ist die Praxis, genau diese Duplikate zu eliminieren und an einem einzigen, versionierbaren Ort zu bündeln.

Was ist das?

Build-Logik-Organisation beschreibt, wie du gemeinsame Gradle-Konfiguration so strukturierst, dass sie sich nicht in jedem Modul wiederholt. Das zentrale Werkzeug dafür sind Convention Plugins – auch precompiled script plugins genannt. Dabei handelt es sich um gewöhnliche Gradle-Plugins, die du innerhalb deines Projekts selbst definierst und dann in beliebigen Modulen anwendest, genau wie ein offizielles Plugin aus Maven Central.

Im Android-Kontext bedeutet das konkret: Statt in zehn Feature-Modulen zehnmal compileSdk = 35, minSdk = 24 und kotlinOptions { jvmTarget = "17" } zu schreiben, fasst du diese Einstellungen in einem Plugin wie android-library-convention zusammen. Ändert sich der Compile-SDK, passt du genau eine Datei an – alle Module folgen automatisch.

Dieses Prinzip ist besonders wertvoll in der Phase „Modern Android Architecture”. Saubere Modul-Grenzen zwischen Presentation-, Domain- und Data-Layer sind nur dann langfristig wartbar, wenn alle Module dieselben Build-Regeln teilen. Abweichungen in einzelnen Modulen führen sonst zu schwer nachvollziehbaren Inkonsistenzen bei Lint, Tests oder dem Release-Build.

Wie funktioniert es?

Es gibt zwei verbreitete Orte, um Convention Plugins unterzubringen:

buildSrc ist ein spezielles Verzeichnis, das Gradle automatisch als Classpath-Dependency behandelt. Es ist der schnellste Einstieg, hat aber einen entscheidenden Nachteil: Jede Änderung in buildSrc invalidiert den Build-Cache aller Gradle-Tasks im gesamten Projekt.

build-logic als Included Build ist die modernere Lösung und wird in den offiziellen Android-Architektur-Empfehlungen bevorzugt. Du erstellst ein separates Gradle-Projekt im Unterordner build-logic und trägst in der Haupt-settings.gradle.kts ein:

// settings.gradle.kts (Wurzelverzeichnis)
includeBuild("build-logic")

Innerhalb von build-logic legst du unter src/main/kotlin/ Kotlin-Dateien an. Jede Datei mit der Endung .gradle.kts wird automatisch zu einem anwendbaren Plugin – der Dateiname bestimmt den Plugin-Bezeichner:

build-logic/
  src/
    main/
      kotlin/
        android-application-convention.gradle.kts
        android-library-convention.gradle.kts
        android-compose-convention.gradle.kts

In android-library-convention.gradle.kts könnte die zentrale Konfiguration so aussehen:

// build-logic/src/main/kotlin/android-library-convention.gradle.kts
plugins {
    id("com.android.library")
    kotlin("android")
}

android {
    compileSdk = 35
    defaultConfig {
        minSdk = 24
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = "17"
    }
}

Ein Feature-Modul wendet das Plugin mit einer einzigen Zeile an:

// feature/home/build.gradle.kts
plugins {
    id("android-library-convention")
}

Alles andere – compileSdk, minSdk, Kotlin-Version – erbt das Modul automatisch aus dem Convention Plugin.

In der Praxis

Der häufigste erste Schritt ist, die Compose-spezifische Konfiguration auszulagern, weil sie in fast jedem UI-Modul identisch anfällt. Convention Plugins dürfen dabei andere Convention Plugins als Basis verwenden:

// android-compose-convention.gradle.kts
plugins {
    id("android-library-convention")
}

android {
    buildFeatures {
        compose = true
    }
    composeOptions {
        kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get()
    }
}

dependencies {
    val bom = libs.androidx.compose.bom
    implementation(platform(bom))
    implementation(libs.androidx.compose.ui)
    implementation(libs.androidx.compose.material3)
    debugImplementation(libs.androidx.compose.ui.tooling)
}

Typische Stolperfalle: Du erstellst das build-logic-Verzeichnis, schreibst deine Plugins – aber Gradle erkennt sie nicht. Der häufigste Grund: includeBuild("build-logic") fehlt in der Haupt-settings.gradle.kts oder steht nach dem dependencyResolutionManagement-Block. Gradle liest settings.gradle.kts sequenziell; includeBuild muss vor dependencyResolutionManagement erscheinen, damit der Plugin-Classpath korrekt aufgebaut wird.

Eine zweite Falle betrifft den Zugriff auf den Versionskatalog: Die build-logic-eigene settings.gradle.kts braucht einen eigenen versionCatalogs-Block, der auf die libs.versions.toml des Hauptprojekts zeigt, sonst stehen libs.*-Accessors in deinen Convention Plugins nicht zur Verfügung:

// build-logic/settings.gradle.kts
dependencyResolutionManagement {
    versionCatalogs {
        create("libs") {
            from(files("../gradle/libs.versions.toml"))
        }
    }
}

Kombinierst du Convention Plugins mit einer libs.versions.toml-Versionskatalog-Datei, hast du eine konsistente Build-Grundlage, die versioniert, reviewbar und für das gesamte Team nachvollziehbar ist.

Fazit

Convention Plugins sind das entscheidende Werkzeug, um Gradle-Konfiguration in wachsenden Android-Projekten unter Kontrolle zu halten. Statt zehn Module einzeln anzupassen, änderst du eine Datei – und alle Betroffenen ziehen nach. Überprüfe jetzt dein eigenes Projekt: Wie viele build.gradle.kts-Dateien wiederholen denselben compileSdk- oder kotlinOptions-Block? Wähle einen dieser Blöcke aus, extrahiere ihn in ein Convention Plugin, und stelle im Code-Review sicher, dass alle Modul-Builds weiterhin grün bleiben. Das ist der direkteste Weg, um zu spüren, wie viel Aufwand zentralisierte Build-Logik im Alltag einspart.

Quellen (2)
Redaktion

Geschrieben von

Redaktion

Das Redaktionsteam recherchiert und schreibt Artikel zu aktuellen Themen rund um Tech, Lifestyle und Ratgeber.