Saltar al contenido principal

Aplicación imperativa obsoleta de los plugins de Gradle de Flutter

Cómo migrar los archivos de compilación de Android Gradle de tu app de Flutter al nuevo formato declarativo.

Resumen

#

Para compilar una app de Flutter para Android, se deben aplicar los plugins de Gradle de Flutter. Históricamente, esto se hacía de forma imperativa con el método heredado e imperativo de script apply de Gradle.

En Flutter 3.16, se agregó soporte para aplicar estos plugins con el bloque declarativo plugins {} de Gradle (también llamado Plugin DSL) y ahora es el enfoque recomendado. Desde Flutter 3.16, los proyectos generados con flutter create utilizan el Plugin DSL para aplicar los plugins de Gradle. Los proyectos creados cuya versión de Flutter sea anterior a la 3.16 deben migrarse manualmente.

Aplicar los plugins de Gradle utilizando el bloque plugins {} ejecuta el mismo código que antes y debería producir binarios de aplicación equivalentes.

Para conocer las ventajas que tiene la nueva sintaxis Plugin DSL sobre la sintaxis de script apply heredada, consulta la documentación de Gradle.

Migrar el ecosistema de aplicaciones para usar el nuevo enfoque también facilitará al equipo de Flutter el desarrollo de los plugins de Gradle de Flutter, y permitirá habilitar nuevas y emocionantes funciones en el futuro, como usar Kotlin en lugar de Groovy en los scripts de compilación de Gradle.

Migrar

#

android/settings.gradle

#

Primero, busca los valores de Android Gradle Plugin (AGP) y Kotlin que utiliza el proyecto actualmente. A menos que se hayan movido, es probable que estén definidos en el bloque buildscript del archivo <app-src>/android/build.gradle. Como ejemplo, considera el archivo build.gradle de una nueva app de Flutter creada antes de este cambio:

groovy
buildscript {
    ext.kotlin_version = '1.7.10'
    repositories {
        google()
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:7.3.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

rootProject.buildDir = '../build'
subprojects {
    project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
    project.evaluationDependsOn(':app')
}

tasks.register("clean", Delete) {
    delete rootProject.buildDir
}

La versión de AGP es el número que aparece al final de la línea classpath 'com.android.tools.build:gradle:7.3.0', por lo tanto, 7.3.0 en este caso. De manera similar, la versión de Kotlin aparece al final de la línea ext.kotlin_version = '1.7.10', en este caso 1.7.10.

A continuación, reemplaza el contenido de <app-src>/android/settings.gradle por lo siguiente, recordando reemplazar {agpVersion} y {kotlinVersion} con los valores identificados anteriormente:

groovy
pluginManagement {
    def flutterSdkPath = {
        def properties = new Properties()
        file("local.properties").withInputStream { properties.load(it) }
        def flutterSdkPath = properties.getProperty("flutter.sdk")
        assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
        return flutterSdkPath
    }()

    includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")

    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}

plugins {
    id "dev.flutter.flutter-plugin-loader" version "1.0.0" // apply true
    id "com.android.application" version "{agpVersion}" apply false
    id "org.jetbrains.kotlin.android" version "{kotlinVersion}" apply false
}

include ":app"

Si realizaste cambios en este archivo, asegúrate de colocarlos después de los bloques pluginManagement {} y plugins {}, ya que Gradle exige que ningún otro código se coloque antes de estos bloques.

El plugin de Gradle de Flutter de configuración (dev.flutter.flutter-plugin-loader) no debe tener apply false (el valor por defecto es true) o debe establecerse explícitamente en true.

android/build.gradle

#

Elimina todo el bloque buildscript del archivo <app-src>/android/build.gradle:

groovy
buildscript {
    ext.kotlin_version = '{kotlinVersion}'
    repositories {
        google()
        mavenCentral()
    }

    dependencies {
        classpath "org.jetbrains.kotlin:gradle-plugin:$kotlin_version"
    }
}

Así es como probablemente terminará ese archivo:

groovy
allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

rootProject.buildDir = '../build'
subprojects {
    project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
    project.evaluationDependsOn(':app')
}

tasks.register("clean", Delete) {
    delete rootProject.buildDir
}

android/app/build.gradle

#

También es necesario realizar los siguientes cambios en el código que, por defecto, se encuentra en <app-src>/android/app/build.gradle. Primero, elimina los siguientes 2 fragmentos de código que utilizan el método de aplicación imperativa heredado:

groovy
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
    throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
groovy
apply plugin: 'com.android.application'
apply plugin: 'com.jetbrains.kotlin.android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

Ahora aplica de nuevo los plugins, pero esta vez utilizando la sintaxis Plugin DSL. En la parte superior de tu archivo, añade:

groovy
plugins {
    id "com.android.application"
    id "kotlin-android"
    id "dev.flutter.flutter-gradle-plugin"
}

"dev.flutter.flutter-gradle-plugin" es el plugin de Gradle de Flutter del proyecto, que es una cadena diferente a la aplicada en settings.gradle(.kts) ("dev.flutter.flutter-plugin-loader").

Finalmente, si tu bloque dependencies contiene una dependencia de "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version", elimina esa dependencia.

groovy
dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

Si era la única dependencia en el bloque dependencies, puedes eliminar el bloque por completo en su lugar.

Validación

#

Ejecuta flutter run para confirmar que tu aplicación se compila e inicia en un dispositivo Android o emulador conectado.

Ejemplos

#

Google Mobile Services y Crashlytics

#

Si tu app utilizaba Google Mobile Services y Crashlytics, elimina las siguientes líneas de <app-src>/android/build.gradle:

groovy
buildscript {
    // ...

    dependencies {
        // ...
        classpath "com.google.gms:google-services:4.4.0"
        classpath "com.google.firebase:firebase-crashlytics-gradle:2.9.9"
    }
}

Luego elimina estas 2 líneas de <app-src>/android/app/build.gradle:

groovy
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'

Para migrar a la nueva sintaxis de aplicación declarativa para los plugins de GMS y Crashlytics, añádelos al bloque plugins en el archivo <app-src>/android/settings.gradle de tu app. Los añadidos deberían ser similares a los siguientes, pero con las versiones de plugins que desees, que probablemente coincidan con las que eliminaste del archivo <app-src>/android/build.gradle.

groovy
plugins {
    id "dev.flutter.flutter-plugin-loader" version "1.0.0"
    id "com.android.application" version "{agpVersion}" apply false
    id "org.jetbrains.kotlin.android" version "{kotlinVersion}" apply false
    id "com.google.gms.google-services" version "4.4.0" apply false
    id "com.google.firebase.crashlytics" version "2.9.9" apply false
}

Añade las siguientes líneas a <app-src>/android/app/build.gradle:

groovy
plugins {
    id "com.android.application"
    id "dev.flutter.flutter-gradle-plugin"
    id "org.jetbrains.kotlin.android"
    id "com.google.gms.google-services"
    id "com.google.firebase.crashlytics"
}

Timeline

#

Soporte en versión estable: 3.16.0 Recomendado en versión estable: 3.19.0

Referencias

#

Los archivos de compilación de Gradle generados por flutter create difieren entre las versiones de Flutter. Para obtener una descripción detallada, consulta el issue #135392. Deberías considerar utilizar las versiones más recientes de los archivos de compilación.