【构建工具】Gradle Kotlin DSL中的大小写陷阱:BuildConfigField

在Android开发当中,BuildConfig是一个非常有用的功能,它允许我们在构建过程中定义常量,并在运行时使用它们。But!!当我们从传统的Groovy DSL迁移到Kotlin DSL时或者被Android Studio坑的时候,有一些细微的差别可能会导致意想不到的问题。今天,我要分享一个我最近遇到的陷阱:BuildConfigField vs buildConfigField(主要是Android Studio的代码的锅!)。

如果你不知道什么是BuildConfig,可以去看我上一篇博客

问题场景

假设有一个使用Kotlin DSL的build.gradle.kts文件,其中包含以下配置:

kotlin 复制代码
android {
    namespace = "dev.xuanran.xxxx"
    compileSdk = 35

    defaultConfig {
        applicationId = "dev.xuanran.xxxx"
        minSdk = 26
        targetSdk = 35
        versionCode = 1
        versionName = "1.0"
    }

    buildTypes {
        debug {
            BuildConfigField("boolean", "DEBUG", "true")
            BuildConfigField("boolean", "APP_PACKAGE_BIND", "false")
        }
        release {
            isMinifyEnabled = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
            BuildConfigField("boolean", "DEBUG", "false")
            BuildConfigField("boolean", "APP_PACKAGE_BIND", "false")
        }
    }
    
    buildFeatures {
        buildConfig = true
    }
    // 其他配置...
}

我们已经启用了BuildConfig功能(通过buildFeatures { buildConfig = true }),但是当查看生成的BuildConfig类时,只看到默认字段:

java 复制代码
public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  public static final String APPLICATION_ID = "dev.xuanran.xxxxx";
  public static final String BUILD_TYPE = "debug";
  public static final int VERSION_CODE = 1;
  public static final String VERSION_NAME = "1.0";
  // 但是没有APP_PACKAGE_BIND字段!
}

问题出在哪???

问题根源:大小写敏感性

问题出在方法名的大小写上。在Kotlin DSL中,正确的方法名应该是小写开头的buildConfigField,而不是大写开头的BuildConfigField

这是因为Kotlin语言和Gradle DSL遵循特定的命名约定:

  • 类名和接口名以大写字母开头(PascalCase)
  • 方法名和属性名以小写字母开头(camelCase)

而在Groovy DSL中,由于Groovy的动态特性,方法调用对大小写不那么敏感,所以可能两种写法都能工作。但在更严格的Kotlin中,这是一个明确的区别。

解决方案

修改build.gradle.kts文件,将所有的BuildConfigField改为buildConfigField

kotlin 复制代码
buildTypes {
    debug {
        buildConfigField("boolean", "DEBUG", "true")
        buildConfigField("boolean", "APP_PACKAGE_BIND", "false")
    }
    release {
        isMinifyEnabled = true
        proguardFiles(
            getDefaultProguardFile("proguard-android-optimize.txt"),
            "proguard-rules.pro"
        )
        buildConfigField("boolean", "DEBUG", "false")
        buildConfigField("boolean", "APP_PACKAGE_BIND", "false")
    }
}

进行这个简单的修改后,重新构建项目,就会看到生成的BuildConfig类中现在包含了自定义字段:

java 复制代码
public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  public static final String APPLICATION_ID = "dev.xuanran.xxxx";
  public static final String BUILD_TYPE = "debug";
  public static final int VERSION_CODE = 1;
  public static final String VERSION_NAME = "1.0";
  public static final boolean APP_PACKAGE_BIND = false; // 然后就可以了
}

错误原因(甩锅Android Studio)

我是知道如果要启用这个功能的话需要使用buildConfigField的,但是我在输入的时候Android Studio只有这一个代码补全,并没有小写字母开头的代码补全(即使我首字母是小写的),然后我就发现生成的并没有我想要的,排查了半天才发现是首字母大小写的问题,而且这个问题Gradle Sync和编译的时候不会报错,但是就是不生成这个字段

结论

我就说Android Studio是整个jetbrain中最烂的ide吧

相关推荐
阿乾之铭3 分钟前
Java后端文件类型检测(防伪造)
java·开发语言
sunbyte10 分钟前
Three.js + React 实战系列 - 联系方式提交表单区域 Contact 组件✨(表单绑定 + 表单验证)
开发语言·javascript·react.js
(ღ星辰ღ)25 分钟前
js应用opencv
开发语言·javascript·opencv
HY小海38 分钟前
【数据结构】双链表
c语言·开发语言·数据结构·学习
Go Dgg1 小时前
Go语言实现豆瓣电影Top250爬虫
开发语言·爬虫·golang
真的想上岸啊1 小时前
c语言第一个小游戏:贪吃蛇小游戏03
c语言·开发语言·算法
User_芊芊君子1 小时前
【Java继承】——面向对象编程的基石
java·开发语言
老理说的好2 小时前
无线定位之 三 SX1302 网关源码 thread_gps 线程详解
开发语言·信息与通信
kyle~2 小时前
C++匿名函数
开发语言·c++·人工智能
lilili啊啊啊2 小时前
iOS safari和android chrome开启网页调试与检查器的方法
android·ios·safari