【构建工具】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 分钟前
数据结构从入门到实战————栈
c语言·开发语言·数据结构·程序人生
sali-tec14 分钟前
C# 基于halcon的视觉工作流-章39-OCR识别
开发语言·图像处理·算法·计算机视觉·c#·ocr
lightqjx15 分钟前
【C++】vector 使用和实现
开发语言·c++
蓝桉~MLGT31 分钟前
Python学习历程——基础语法(print打印、变量、运算)
开发语言·python·学习
风起云涌~37 分钟前
【Android】kotlin.flow简介
android·开发语言·kotlin
深海呐41 分钟前
Android 协程的基本使用和最简要原理概述
android·协程·android 协程·协程的原理
楼田莉子1 小时前
C++学习:C++类型转换专栏
开发语言·c++·学习
David WangYang1 小时前
便宜的自制 30 MHz - 6 GHz 矢量网络分析仪
开发语言·网络·php
诗句藏于尽头1 小时前
关于七牛云OSS存储的图片数据批量下载到本地
开发语言·windows·python
楼田莉子1 小时前
C++IO流学习
开发语言·c++·windows·学习·visual studio