androidgradleandroid-gradle-7.0

Cannot run Project.afterEvaluate(Action) when the project is already evaluated


Project type: Android

Gradle wrapper: gradle-7.5

Gradle plugin: 7.4.2

app module build.gradle:

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id "org.jetbrains.kotlin.kapt"
}

android {
    ...

    defaultConfig {
        ...
    }

    flavorDimensions "app", "channel"
    productFlavors {
        dev {
            dimension "app"
            applicationIdSuffix ".dev"
        }

        product {
            dimension "app"
        }

        google {
            dimension "channel"
        }

        android.applicationVariants.all { variant ->
            def dirPath = project.projectDir.absolutePath + '/build/outputs/apk/' + dirName + '/'
            def filePath = ''
            variant.outputs.all {
                outputFileName = "xxx.apk"
                filePath = outputFileName
            }

            variant.getAssembleProvider().get().doLast {
                if (variant.buildType.name == 'release') {
                    def cmd = 'cd .. && ./ossutilmac64 cp -f ' + dirPath + filePath + ' oss://android-test-sz/' + filePath
                    exec {
                        ExecSpec execSpec ->
                            executable 'zsh'
                            args '-c', cmd
                            standardOutput = out
                    }
                    println(out.toString())
                }
            }
        }
    }
}

dependencies {
    ...
}

when I run shell “./gradlew assembleDevGoogleRelease” to build apk and upload apk to oss with Gradle 7, unfortunately, the build fails. (Gradle 6.x is ok)

> Task :app:assembleDevGoogleRelease FAILED

FAILURE: Build failed with an exception.

* Where:
Build file '...app/build.gradle' line: 222

* What went wrong:
Execution failed for task ':app:assembleDevGoogleRelease'.
> Cannot run Project.afterEvaluate(Action) when the project is already evaluated.

The error line 222 is the “exec {” in doLast.

Any help is much appreciated. Thanks in advance. :slight_smile:


Solution

  • You should place the applicationVariants.all on the outside block

    plugins {
        id 'com.android.application'
        id 'org.jetbrains.kotlin.android'
        id 'org.jetbrains.kotlin.kapt'
    }
    
    android {
        // ...
    
        defaultConfig {
            // ...
        }
    
        flavorDimensions 'app', 'channel'
        productFlavors {
            dev {
                dimension 'app'
                applicationIdSuffix '.dev'
            }
    
            product {
                dimension 'app'
            }
    
            google {
                dimension 'channel'
            }
        }
    }
    
    android.applicationVariants.all { variant ->
        def dirPath = project.projectDir.absolutePath + '/build/outputs/apk/' + dirName + '/'
        def filePath = ''
        variant.outputs.all {
            outputFileName = "xxx.apk"
            filePath = outputFileName
        }
    
        variant.getAssembleProvider().get().doLast {
            if (variant.buildType.name == 'release') {
                def cmd = 'cd .. && ./ossutilmac64 cp -f ' + dirPath + filePath + ' oss://android-test-sz/' + filePath
                exec {
                    executable 'zsh'
                    args '-c', cmd
                    standardOutput = out
                }
                println(out.toString())
            }
        }
    }