将 gradle 更新到 7.0.3 后 buildConfigField 不起作用

Posted

技术标签:

【中文标题】将 gradle 更新到 7.0.3 后 buildConfigField 不起作用【英文标题】:buildConfigField not working after updating gradle to 7.0.3 【发布时间】:2021-12-02 22:44:21 【问题描述】:

我将gradle4.0.1更新为7.0.3,因为我需要新gradle的支持。

我让自动更新程序运行,完成后,当我运行代码时出现以下错误:

C:\Users\me\Projects\proj\proj\proj\app\build\generated\source\buildConfig\stage\debug\proj\BuildConfig.java:22: error: illegal forward reference
public static final String APPLICATION_LIST_URL = BACKEND_HOST + "/page";

build.gradle 中,buildConfigField 声明如下:

defaultConfig 
    applicationId "my.app.id"
    minSdkVersion 21
    versionCode getBuildTimestamp()
    versionName "2.0.0"

    buildConfigField 'String', 'APPLICATION_LIST_URL', 'BACKEND_HOST + "/page"'


我尝试了Invaldiate cache/restart,但我不知道我还能尝试什么。

编辑 BACKEND_HOST 也被定义:

productFlavors 
    local 
        dimension "type"
        targetSdkVersion 30
        buildConfigField 'String', 'APK_DOWNLOAD_RESOLVE_URL', 'BACKEND_HOST + "DOES_NOT_EXIST"'
        ...
    

    remote 
        dimension "type"
        targetSdkVersion 30
        applicationIdSuffix ".remote"
        buildConfigField 'String', 'APK_DOWNLOAD_RESOLVE_URL', 'BACKEND_HOST + "/remote/download"'
    

    def backendRemote= '"https://myUrl"'

    android.applicationVariants.all 
        variant ->
            def appName = "myApp"
            def backendHost = backendRemote
            variant.resValue "string", "app_name", appName
            resValue "string", "app_version", "$appName $variant.versionName"
            variant.buildConfigField "String", "AUTH_HOST", backendHost
            variant.buildConfigField "String", "BACKEND_HOST", backendHost
    

我是用 remote 风格构建的

【问题讨论】:

您在哪里/如何定义 BACKEND_HOST? 【参考方案1】:

目前尚不清楚构建工具如何确定 BuildConfig 中字段声明的顺序。但有效的是这个(注意BuildConfig.BACKEND_HOST 而不仅仅是BACKEND_HOST):

buildConfigField 'String', 'BACKEND_HOST', 'my.backend.host.com'
buildConfigField 'String', 'APPLICATION_LIST_URL', 'BuildConfig.BACKEND_HOST + "/page"'

https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html 的第 8.3.3 章解释了哪些前向引用是合法的,哪些是非法的。

这是一个最小的代码示例,展示了如何在每种风格中定义 BACKEND_HOST:

    defaultConfig 
        applicationId "com.example.myapplication"
        minSdk 30
        targetSdk 31
        versionCode 1
        versionName "1.0"

        buildConfigField 'String', 'APPLICATION_LIST_URL', 'BuildConfig.BACKEND_HOST + "/page"'
    

    flavorDimensions "version"
    productFlavors 
        free 
            dimension "version"
            buildConfigField "String", "BACKEND_HOST", '"www.free.com"'
        
        paid 
            dimension "version"
            buildConfigField "String", "BACKEND_HOST", '"www.paid.com"'
        
    

这是可行的,因为在不太具体的(defaultConfig)之前首先评估更具体的 BuildConfig 字段(风格)。

此代码是从 OP 的问题中复制的,并通过引用 BACKEND_HOST static 进行修改以进行编译:

    defaultConfig 
        applicationId "my.app.id"
        minSdkVersion 21
        versionCode getBuildTimestamp()
        versionName "2.0.0"

        buildConfigField 'String', 'APPLICATION_LIST_URL', 'BuildConfig.BACKEND_HOST + "/page"'
        buildConfigField "String", "BACKEND_HOST", '"www.paid.com"'
    


    flavorDimensions "type"
    productFlavors 
        local 
            dimension "type"
            targetSdkVersion 30
            buildConfigField 'String', 'APK_DOWNLOAD_RESOLVE_URL', 'BuildConfig.BACKEND_HOST + "DOES_NOT_EXIST"'
        

        remote 
            dimension "type"
            targetSdkVersion 30
            applicationIdSuffix ".remote"
            buildConfigField 'String', 'APK_DOWNLOAD_RESOLVE_URL', 'BuildConfig.BACKEND_HOST + "/remote/download"'
        
    

    def backendRemote= '"https://myUrl"'

    android.applicationVariants.all 
        variant ->
            def backendHost = backendRemote
            variant.buildConfigField "String", "AUTH_HOST", backendHost
            variant.buildConfigField "String", "BACKEND_HOST", backendHost
    

【讨论】:

对不起,我忘记加了,但是已经定义好了 在问题中添加了它 我可以重现该问题并找到解决方法@Richard 为什么我的应用程序是这样构建的,因为有 3 种不同的风格,而 backend_host 取决于构建的风格。我不认为我可以创建这样的静态后端主机。但是如果你说你遇到了同样的错误并且静态后端主机解决了这个问题,那么我会调查一下,谢谢。 看来我误解了你的回答。在我的BuildConfig 中,我可以看到BACKEND_HOST 已定义,并且它下面的变量正在工作,而它上面的变量则没有。不确定如何从 gradle 文件中的 BACKEND_HOST 下的 defaultConfig 获取那些。因为在defaultConfig 中,我实际上有大约 10 个使用 BACKEND_HOST 的变量,其中 3 个在 BuildConfig.java 中高于它,而在它之下的其他 7 个正在工作,但不确定是什么决定了它们在那里订购。但是你帮了我很多,谢谢。

以上是关于将 gradle 更新到 7.0.3 后 buildConfigField 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

将 Gradle 2.1.0 更新到 2.2.1 后出现 NoClassDefFoundError

将 Android Studio 3.6 和 Gradle 更新到 3.5.0 后无法运行项目

将 android studio 更新到 4.2 Beta1 后,Gradle 构建失败

更新到3.0后,Gradle构建失败

更新到 Android Studio 3.2 后,Gradle 构建卡住并且永远不会完成

Unity打包报错 com.android.buil.gradle.internal.tasks.workers$ActionFacade