惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Apple Machine Learning Research
Apple Machine Learning Research
Recent Announcements
Recent Announcements
IT之家
IT之家
人人都是产品经理
人人都是产品经理
G
Google Developers Blog
Microsoft Azure Blog
Microsoft Azure Blog
博客园_首页
大猫的无限游戏
大猫的无限游戏
U
Unit 42
罗磊的独立博客
博客园 - Franky
WordPress大学
WordPress大学
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
M
MIT News - Artificial intelligence
SecWiki News
SecWiki News
V
Vulnerabilities – Threatpost
P
Privacy International News Feed
P
Palo Alto Networks Blog
F
Fortinet All Blogs
P
Proofpoint News Feed
博客园 - 叶小钗
C
CERT Recently Published Vulnerability Notes
T
Tor Project blog
Spread Privacy
Spread Privacy
S
Securelist
C
Cisco Blogs
I
Intezer
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Cyberwarzone
Cyberwarzone
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Privacy & Cybersecurity Law Blog
宝玉的分享
宝玉的分享
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Engineering at Meta
Engineering at Meta
S
Schneier on Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
GbyAI
GbyAI
T
Troy Hunt's Blog
T
Threatpost
博客园 - 司徒正美
Y
Y Combinator Blog
Hugging Face - Blog
Hugging Face - Blog
AWS News Blog
AWS News Blog
T
The Blog of Author Tim Ferriss
G
GRAHAM CLULEY
N
Netflix TechBlog - Medium
酷 壳 – CoolShell
酷 壳 – CoolShell
Google DeepMind News
Google DeepMind News
Know Your Adversary
Know Your Adversary
S
SegmentFault 最新的问题

Kenvix's Blog

实现带有Nvidia GPU+Rootless Podman+Docker+Systemd+自动驱动注入支持的systemd nspawn容器 | Kenvix's Blog 手动保留常用端口,解决 Windows 端口被 Hyper-V / WinNAT 占用的问题 免Telent/TTL屏蔽运营商新版光猫的远控、TR069和RMS,获取动态随机超级管理员密码并固化权限 | Kenvix's Blog 利用Windows卷影副本(Volume Shadow)找回被覆盖和删除的数据 | Kenvix's Blog 在Windows下实现WireGuard动态DNS解析(DDNS)的正确方法:避免无意义的开销 | Kenvix's Blog OpenWRT/DNSMasq 配置DHCP静态路由主动推送 实现流量直达和旁路由流量零代价分载 | Kenvix's Blog 解决 Windows 打开视频/图片文件夹很慢的问题 | Kenvix's Blog AltA2DP - 向支持Sony LDAC协议的耳机提供Windows下蓝牙LDAC音频编码器支持 | Kenvix's Blog (2024更新)修复黑群晖 DSM7.0 + Btrfs 存储空间/磁盘损毁/堪用 的问题 校园网白嫖思路分享:局域网中转-不花钱、不认证、高速上网 | Kenvix's Blog 在 Windows 上配置网卡多个 VLAN、多个虚拟网卡、实现单线多拨网速叠加(无需驱动支持) | Kenvix's Blog 解决视频彩铃、语音通话自动转视频通话导致打电话自动挂断的问题 | Kenvix's Blog 超低成本廉价考研教程:如何用小于¥500甚至¥300的开销考个研 | Kenvix's Blog 在 Ubuntu 21.10 上启用蓝牙 LDAC/AAC/AptX 高质量音频编码支持 在 VMware Workstation 桥接模式的网卡上让虚拟机使用 VLAN 的正确方法 在 Windows 上设置 NAT 或网络共享的正确方法——避免Wi-Fi热点无法使用 自编译 红米 AC2100 OpenWRT R21.7.26 Linux 内核结构和子系统简介 | Kenvix's Blog Java 快速读取文本 (算法竞赛适用) | Kenvix's Blog 利用 ThreadLocal + Lambda,实现有状态变量的单例模式 | Kenvix's Blog 状态压缩的动态规划问题:骨牌完全覆盖棋盘问题 | Kenvix's Blog 我的 Windows 10 2004 新增 Bug 解决办法记录 解决 Android Studio 及 IDEA 中 Gradle 错误信息乱码的问题 Kotlin 的那些骚操作 | Kenvix's Blog 修复国行 MIUI 打开 Google Play 始终提示 DF-DFERH-01 的问题 解决 VSCode 持续调用 WMIC 导致一个 CPU 核心完全被占满的问题 扔鸡蛋问题 | Kenvix's Blog 计算机幻觉从入门到入土 | Kenvix's Blog Java 注解预处理 Annotation Processing & 代码生成 Ubuntu 上通过以太网分享网络连接(NAT) | Kenvix's Blog Windows 选择指定的网卡来开承载网络型热点 | Kenvix's Blog 修复升级 Windows10 版本后所有内置应用闪退+第三方应用参数错误的问题 | Kenvix's Blog 配置用于 Gradle6.x + MySQL 8 的 jOOQ 3.14 代码自动生成 (已更新) 修复 Windows 环境下的程序访问 WSL 中的 MySQL 提示 Access Denied 的问题 修复 WSL 下 PHP+FastCGI 卡死的问题 使用任意磁盘或路径保存 Windows 文件历史记录 | Kenvix's Blog [1.12.2+Mod] MoeCraft :: 自由开放的科技向公益 Mod 服务器 Kenvix's Blog 禁用使用Intel核显的Windows笔记本自动调节亮度功能 | Kenvix's Blog 真正实现Minecraft高级登录(外置登录)的几种方案 | Kenvix's Blog 谈谈神舟的两艘贼船,Z7M-KP7S1 / Z7M-KP7SC USBCopyer: 插上U盘自动按需复制文件 | Kenvix's Blog USBCopyer 回调功能详细说明 | Kenvix's Blog C# 实现自定义"应用程序设置"的配置文件(user.config)存储路径 | Kenvix's Blog Win10 资源管理器为所有格式激活“编辑”按钮并修改文本文件“编辑”按钮的编辑器 | Kenvix's Blog 留言板 | Kenvix's Blog 又一次 Hello world | Kenvix's Blog Java 学习笔记 (仍在更新) | Kenvix's Blog 在Win10 Pro下挂载NFS(网络文件系统) | Kenvix's Blog Nginx 反向代理 Aria2 JSONRPC | Kenvix's Blog (Android6.0~9.0) 清除锁屏密码 | Kenvix's Blog WordPress 更换站点地址后批量修改文章/评论中的旧地址 | Kenvix's Blog 修复一加3/3T因固件过老导致刷入ROM时提示错误7的问题 | Kenvix's Blog 修复Android DM-Verity 警告 | Kenvix's Blog 贴吧云签到 资源索引(下载|文档|插件) | Kenvix's Blog 继续监控!使用树莓派+Motion实现实时视频监控并通过浏览器查看 | Kenvix's Blog 自动获取Pixiv每日排行榜第一张图片(600x600 | 可用于博客背景图) | Kenvix's Blog 使用树莓派实现定时拍照监控并发送邮件到邮箱 | Kenvix's Blog 好压 V2.7 Beta1 绿色版——功能强大,良心的压缩软件 | Kenvix's Blog 任意语言实现读取压缩包注释 | Kenvix's Blog 自己实现QQ群自定义分享(管理员开启了群交易?) | Kenvix's Blog MoeCDN - 加速Gravatar/GoogleAPIs等无法在国内访问的资源 | Kenvix's Blog [Minecraft] WebLogin-连接到你的服务器来检查玩家是否可以登录 | Kenvix's Blog Android卡刷包提示This package is for device: ... this device is ...的解决方案 Kenvix's Blog 给EMLOG评论框加上复选框[√]防止垃圾评论 | Kenvix's Blog 欢迎使用emlog | Kenvix's Blog
在普通的 Gradle Java/Kotlin 项目中使用 BuildConfig
2019-08-20 · via Kenvix's Blog

简介

Android Studio 为其 Android 项目提供了十分方便的 BuildConfig 功能,该功能在运行编译时自动生成 BuildConfig.java 文件,其中储存了编译时的一些系统信息(如APP版本号、渠道、编译时间、编译器等),并可以用于条件编译。

所幸,有人已经仿照出了具有类似功能的 Gradle 插件。本文将说明如何使用这个插件。

使用方法

1. 添加依赖

build.gradle 文件中

plugins {
    id 'java'
    id 'de.fuerstenau.buildconfig' version '1.1.8' //添加 BuildConfig 插件
}

plugins 节应位于 importbuildscript 节的后面

2. 定义项目属性

例如,对于项目 com.kenvix.moecraftbot.ng

group 'com.kenvix'
version '1.0'
def applicationName = 'MoeCraftBotNG'
def versionCode = 1

archivesBaseName = 'moecraftbot.ng'
def mainSrcDir = 'src/main/java'  //项目java源代码目录
def fullPackageName = "${group}.$archivesBaseName"
def fullPackagePath = fullPackageName.replaceAll('.', '/')
def isReleaseBuild = System.getProperty("isReleaseBuild") != null //根据环境变量判断是否为正式发行版(判断是否是Release版本的构建)

3. 添加 BuildConfig 信息

/*********************************************************************/
/**                 Application Build Config Settings               **/
/*********************************************************************/

buildConfig {
    appName = project.name       // sets value of NAME field
    version = project.version   // sets value of VERSION field,
    // 'unspecified' if project.version is not set

    clsName = 'BuildConfig'      // sets the name of the BuildConfig class
    packageName = fullPackageName  // sets the package of the BuildConfig class,
    // 'de.fuerstenau.buildconfig' if project.group is not set
    charset = 'UTF-8'            // sets charset of the generated class,
    // 'UTF-8' if not set otherwise

    buildConfigField 'String', 'APPLICATION_NAME', applicationName
    buildConfigField 'String', 'VERSION_NAME',     version as String
    buildConfigField 'int',    'VERSION_CODE',     versionCode as String
    buildConfigField 'long',   'BUILD_UNIXTIME',   System.currentTimeMillis() + 'L'
    buildConfigField 'java.util.Date', 'BUILD_DATE', 'new java.util.Date(' + System.currentTimeMillis() + 'L)'

    buildConfigField 'String', 'BUILD_USER',       System.getProperty("user.name")
    buildConfigField 'String', 'BUILD_JDK',        System.getProperty("java.version")
    buildConfigField 'String', 'BUILD_OS',         System.getProperty("os.name")
    buildConfigField 'boolean','IS_RELEASE_BUILD', isReleaseBuild as String

其中,buildConfigField 表示这是自定义字段,后面紧随的是字段类型,要用字符串书写类名。(例如 'String'

其后是字段名称 'APPLICATION_NAME'(同样用字符串),其后是内容,也必须是字符串。如果内容为 intboolean 等类型,则必须强制转换。

内容部分可以书写代码,以字符串形式书写即可。

4. 让 IDE 识别代码

默认 IDE 不会识别 BuildConfig 生成的代码,为此要手动将其加入 sourceSets

// Add generated build-config directories to the main source set, so that the
// IDE doesn't complain when the app references BuildConfig classes
sourceSets.main.java {
    srcDirs += new File(mainSrcDir) //项目本身源代码
    srcDirs += new File(buildDir, 'gen/buildconfig/src') //BuildConfig
}

5. 生成项目

刚才我有提到“判断是否是Release版本的构建”,可以这样使用它:

例如,在打包 jar 时,可以在 gradle 命令上添加 JVM 参数 -DisReleaseBuild=true 来将 isReleaseBuild 设置为 true,让项目执行在 BuildConfig.IS_RELEASE_BUILD == true 时的代码,从而达到条件编译的效果。

项目生成后, BuildConfig 效果应该如下图所示:

配置到此结束。

我们还可以在项目启动时打印一下版本信息:

println("${BuildConfig.APPLICATION_NAME} Ver.${BuildConfig.VERSION_NAME} By Kenvix")

println("Built at ${BuildConfig.BUILD_DATE.format()} By ${BuildConfig.BUILD_USER} @ ${BuildConfig.BUILD_OS} JDK ${BuildConfig.BUILD_JDK}")

if (!BuildConfig.IS_RELEASE_BUILD)
    println("Debug build")