原始网页直通车

每个项目中, Gradle 都会帮助我们生成一个 BuildConfig ,那么:

  1. 这个类有何用处?
  2. 是在项目的编译期间,哪个环节、如何生成的?

BuildConfig 的用处

项目编译成功后,会在每一个 module 下的 build/generated/source/buildConfig/debug(release)/包名 下生成一个 BuildConfig 文件。内容如下:

public final class BuildConfig {public static final boolean DEBUG = Boolean.parseBoolean("true");public static final String APPLICATION_ID = "com.example.myapplication";public static final String BUILD_TYPE = "debug";public static final int VERSION_CODE = 1;public static final String VERSION_NAME = "1.0";
}

从内容可以很明显的看出来, BuildConfig 是根据 module 下的 build.gradle 生成的。

其中最常用的是 BuildConfig.DEBUG ,判断当前包环境是否是 debug 环境,用来控制日志的输出等。这个值会根据开发者的 Build 类型自动设定,不需要手动设置。

除此之外,我们还可以自定义添加 BuildConfig 里的常量,比如设置开发环境和正式环境下的网络请求地址等。

modulebuild.gradle 文件中的 defaultConfigbuildTypes 节点中使用 buildConfigField 关键字即可。区别在于 buildTypes 会根据 Build 类型引用不同的值, defaultConfig 是通用的值。

buildConfigField "String", "BASE_STRING", "\"string content\"" 这句代码中三个参数分别是 数据类型,常量名,常量值。
注意的是 BuildConfig 是通过 String 读取数据的,所以当常量值数据类型为 String 时,需要在双引号里面在添加一个双引号并转义。

defaultConfig {applicationId "com.example.myapplication"minSdkVersion 21targetSdkVersion 29versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"buildConfigField "String", "BASE_STRING", "\"string content\""buildConfigField "boolean", "BASE_BOOLEAN", "false"buildConfigField "int", "BASE_INT", "1"}buildTypes {release {buildConfigField "String", "BASE_URL", "\"http://www.google.com.hk\""minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}debug {buildConfigField "String", "BASE_URL", "\"http://www.baidu.com\""minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}

生成的 BuildConfig.java 如下:

public final class BuildConfig {public static final boolean DEBUG = Boolean.parseBoolean("true");public static final String APPLICATION_ID = "com.example.myapplication";public static final String BUILD_TYPE = "debug";public static final String FLAVOR = "";public static final int VERSION_CODE = 1;public static final String VERSION_NAME = "1.0";// Fields from build type: debugpublic static final String BASE_URL = "http://www.baidu.com";// Fields from default config.public static final boolean BASE_BOOLEAN = false;public static final int BASE_INT = 1;public static final String BASE_STRING = "string content";
}

常量值的可以直接写在 build.gradle 中,不过更推荐定义在 gradle.properties 中,然后在 build.gradle 中引用即可。

gradle.properties 中定义:

BASE_STRING = "string content"
BASE_BOOLEAN = false
BASE_INT = 1

build.gradle 中引用:

buildConfigField "String", "BASE_STRING", BASE_STRING
buildConfigField "boolean", "BASE_BOOLEAN", BASE_BOOLEAN
buildConfigField "int", "BASE_INT", BASE_INT

因为 gradle.properties 里定义的 value 默认都是 String ,所以在 build.gradle 中可以直接使用

BuildConfig 的生成

翻开 Gradle 的源码,找到 BuildConfigGenerator 这个类,具体看下 generate() 这个方法:(精简后)

public void generate() throws IOException {// 创建BuildConfig.java的File对象File buildConfigJava = new File(pkgFolder, BUILD_CONFIG_NAME);try {// 根据刚刚创建的File对象,创建JavaWriter对象,// 这个对象就是用来生成java源码文件的JavaWriter writer = closer.register(buildConfigJava);// 写入BuildConfig顶部的文档描述writer.emitJavadoc("Automatically generated file. DO NOT MODIFY")// 写入包名.emitPackage(mBuildConfigPackageName)// 定义BuildConfig类.beginType("BuildConfig", "class", PUBLIC_FINAL);// 遍历写入在build.gradle中定义的常量for (ClassField field : mFields) {emitClassField(writer, field);}// 完成writer.endType();} finally {closer.close();}
}

可以看到, BuildConfig 这个类以及它里面的内容,就是在这个方法中利用 square 的开源项目 javapoet - JavaWriter 来生成的。

BuildConfig 是在哪个环节中生成的?

我们顺瓜模藤来找到调用 generate() 的源头:

BuildConfigGenerator ->
GenerateBuildConfig.generate() ->
TaskManager.createBuildConfigTask() ->
(ApplicationTaskManager, LibraryTaskManager).createTasksForVariantScope ->
VariantManager.createAndroidTasks() ->
BasePlugin.createAndroidTasks() ->
BasePlugin.createTasks() ->
BasePlugin.basePluginApply() ->
BasePlugin.apply()

可以看到调用链的源头就是 BasePluginapply 方法,但要搞清楚生成 BuildConfig 的任务执行时机,还是要看 ApplicationTaskManagerLibraryTaskManagercreateTasksForVariantScope 方法:(精简后)

public void createTasksForVariantScope(@NonNull final VariantScope variantScope) {createAnchorTasks(variantScope);createCheckManifestTask(variantScope);// Add a task to publish the applicationId.createApplicationIdWriterTask(variantScope);// Add a task to process the manifest(s)createMergeApkManifestsTask(variantScope);// Add a task to create the res valuescreateGenerateResValuesTask(variantScope);// Add a task to merge the resource folderscreateMergeResourcesTask(variantScope);// Add tasks to compile shadercreateShaderTask(variantScope);// Add a task to merge the asset folderscreateMergeAssetsTask(variantScope);createLibraryAssetsTask(variantScope);// Add a task to create the BuildConfig classcreateBuildConfigTask(variantScope);createAidlTask(variantScope);// Add a compile taskcreateCompileTask(variantScope);// Create the lint tasks, if enabledcreateLintTasks(variantScope);
}

可以看到是在 MergeResourcesMergeAssets 之后才生成的,生成之后,就开始生成 AIDL 文件的 java 代码了。

聊一下 Gradle 相关,BuildConfig 这个类是如何生成的?相关推荐

  1. 这一次彻底弄明白Gradle相关配置

    这一次彻底弄明白Gradle相关配置 鸿洋 鸿洋 微信号 hongyangAndroid 功能介绍 你好,欢迎关注鸿洋的公众号,每天为您推送高质量文章,让你每天都能涨知识.点击历史消息,查看所有已推送 ...

  2. Android Studio构建时报gradle相关错误的解决办法

    坑1:Connection timed out: connect. If you are behind an HTTP proxy, please configure the proxy settin ...

  3. 【Android Gradle 插件】Gradle 映射文件 ( settings.gradle 映射为 Settings 类 | build.gradle 映射为 Project 类 )

    文章目录 一.settings.gradle 映射为 Settings 类 二.build.gradle 映射为 Project 类 Android Plugin DSL Reference 参考文档 ...

  4. JAVA的静态方法的运算_java. util.Math类是数学相关的工具类,里面提供了大量的静态方法,完成与数学运算相关的操作。...

    java. util.Math类是数学相关的工具类,里面提供了大量的静态方法,完成与数学运算相关的操作. /* public static double abs ( double num):获取绝对值 ...

  5. gradle相关配置内容解析

    gradle 项目的构建工具,基于groovy语言.主要用于管理依赖包. as中一般将gradle下载在C:\Documents and Settings<用户名>.gradle\wrap ...

  6. 小程序生成统一支付prepay_id相关配置和类介绍

    prepay_id微信官方名称叫预支付交易会话标识, 是小程序实现支付功能, 必须要获取的一个参数, prepay_id的有效期是7200秒. 很多朋友在做小程序支付开发时, 不知道怎么得到这个参数. ...

  7. 分享一个自己写的取中国农历相关数据的类。包含:农历年月日,生肖,星座,年龄,天干,地支等方法...

    分享一个自己写的取中国农历相关数据的类.包含:农历年月日,生肖,星座,年龄,天干,地支等方法.此类自己花了一上午的时间写的,适用于像相亲网等类似的网站 主要使用了微软针对东亚地区的农历类Chinese ...

  8. mysql反向生成uml类图_UML类图自动生成,太爽了

    最近在开发的过程当中,对于已有的代码,想将相关类绘制成UML类图,虽然现在有很多UML类图的优秀软件,比如ProcessOn(可视化编辑).draw.io(可视化编辑).PlantUML(代码生成), ...

  9. 实体类的动态生成(三)

    前言 在 .NET 中主要有两种动态生成并编译的方式,一种是通过 System.Linq.Expressions 命名空间中的 LambdaExpression 类的 CompileToMethod( ...

最新文章

  1. 【新星计划】MATLAB-定义函数
  2. zongzi tutorial
  3. QT的QBluetoothDeviceDiscoveryAgent类的使用
  4. Integer的==问题
  5. MySQL 基础---数据库维护和性能提高
  6. OpenStack推出最新版本Newton,显著提升单一云平台 对虚拟化、裸机和容器的管理...
  7. python图像对比_Python多种图像处理库的比较与比较
  8. scm中mysql作用_scm供应链管理的作用
  9. 如何在keil5中定义结构变量
  10. 概率论应用题,模型汇总(排去抽球模型)
  11. xshell 6查看测试日志
  12. 参考文献中不同符号的含义
  13. 读取xml文件信息并存入数据库
  14. 【去雾】|GMAN 去雾
  15. 港科夜闻|香港科大商学院院长谭嘉因:金融业仍渴才,商科生疫情下有优势...
  16. [译] 为数字优先新闻编辑室开发文本编辑器
  17. python基础代码汇总
  18. android源码里嵌入蒙古文字体
  19. 儿童计算机知识科普ppt,儿童科普通信知识.ppt
  20. 梦想世界服务器维护,《梦想世界》2012年8月23日服务器维护公告

热门文章

  1. ESP32开发--一键配网与Airkiss配网
  2. 抽丝剥茧C语言(高阶)文件操作+练习
  3. linux数据库入门
  4. Mac电脑修改用户头像操作步骤
  5. 数据结构——CCF真题:疲劳度问题
  6. 安装vs时遇见进度条走完之后界面就消失了怎么办
  7. .net ajax 服务器,以服务器端为中心的 ASP.NET AJAX 模式(2)-陈广琛 | Microsoft Docs
  8. Hbuild 开发H5 APP上架App Store流程
  9. directx修复工具win7_win10下安装win7双系统后启动没有引导菜单怎么解决
  10. 基于JAVA房屋中介管理计算机毕业设计源码+系统+lw文档+部署