Keep Flutter Plugins Alive on Old and New AGP Without Breaking Changes
Plugin maintainers who ship libraries used across a wide Flutter version range face a real split: either drop legacy users or risk build crashes. This technique keeps the install base intact while satisfying the new AGP constraints, and it exposes how Flutter's own tooling scans for KGP usage — a detail that can trip up any Android plugin author.
Starting with Flutter 3.44 and AGP 9.0, Kotlin support is built into the Android Gradle Plugin. Any plugin that still applies `kotlin-android` directly will trigger build warnings now and hard failures later. The official migration path demands a minimum Flutter version bump to 3.44, which abandons users on older releases. A conditional Gradle configuration sidesteps this trade-off by checking the AGP major version and the `android.builtInKotlin` property at configuration time. It applies the Kotlin plugin only when the built-in support is absent, and it selects the correct JVM target DSL based on whether the Kotlin extension exposes `compilerOptions`. String concatenation tricks defeat Flutter CLI's static regex scanner, which otherwise flags any literal `apply plugin: "kotlin-android"` even inside a dead branch. The result is a single plugin codebase that compiles cleanly from Flutter 3.0 through 3.44 and beyond, with no breaking version bump and no manual `gradle.properties` workarounds required from consumers.
The Flutter toolchain's reliance on static regex scanning rather than AST or runtime evaluation creates a cat-and-mouse game where plugin authors must obfuscate valid Groovy to pass a lint check.
AGP's move to built-in Kotlin simplifies the top-level app project but pushes complexity onto library maintainers, who now carry version-detection logic that the platform itself could provide through a standard Gradle property.
The two JVM target DSLs — `kotlinOptions` and `compilerOptions` — coexist awkwardly because Kotlin Gradle Plugin 1.9+ changed the API without a clean compatibility shim, forcing every multi-target plugin to write its own feature detection.