一、前言
当我们在Android Studio创建一个工程的时候,都会存在 local.properties 和 gradle.properties 两个文件,如下图
Properties其实是Java项目中的配置文件,不是Gradle独创的。因为Gradle语法可以和Java进行混合使用,所以在Java项目上面使用Properties文件的方式,在Gradle上面也可以使用。
获取 gradle.properties 的内容不需要我们额外写任何代码,可以直接在build.gradle中进行调用。local.properties 是 Android Studio 配置SDK和NDK一些路径,还不可以直接调用。
二、Properties
了解Properties,其实最主要是了解它的数据格式。Properties
数据格式以键值对的方式:key=value
"#"作为注释使用
三、Gradle中使用properties
1、gradle.properties
因为 Gradle 内置了对 gradle.properties 的调用方式,所以 build.gradle 可以直接获取 gradle.properties 中的内容。
需要注意的是 gradle.properties 中的value是都不需要带 "" ,Gradle 会先把值转换为String类型。
gradle.properties:
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# 版本号
VERSION_CODE=1
# 版本名称
VERSION_NAME=1.0.0
# 包名
APPLICATION_ID=com.example.properties
# 应用名称
APP_NAME=简书
# 应用渠道
APP_CHANNEL=official
# 是否Debug
IS_DEBUG=true
build.gradle:
apply plugin: 'com.android.application'
// 打印日志
println "VERSION_CODE = " + VERSION_CODE.toInteger()
println "VERSION_NAME = " + VERSION_NAME.toString()
println "APPLICATION_ID = " + APPLICATION_ID.toString()
println "APP_NAME = " + APP_NAME.toString()
println "APP_CHANNEL = " + APP_CHANNEL.toString()
if (IS_DEBUG.toBoolean()) {
println "IS_DEBUG is true"
} else {
println "IS_DEBUG is false"
}
android {
compileSdkVersion 28
buildToolsVersion "28.0.3"
defaultConfig {
applicationId APPLICATION_ID.toString()
minSdkVersion 19
targetSdkVersion 28
versionCode VERSION_CODE.toInteger()
versionName VERSION_NAME.toString()
}
productFlavors {
official {
manifestPlaceholders = [
APP_NAME: APP_NAME.toString()
]
}
}
}
AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="${APP_NAME}"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
</application>
</manifest>
Run:
构建APK文件输出的日志,可以看到输出的结果
也可以通过AndroidManifest.xml实时查看,点击Merged Mainfest:
这里可能很多人都不知道,AndroidManifest.xml 中出现Merge错误也可以从这里定位
2、其他 .properties文件
2-1、第一种获取方式:
config.properties(新建):
value不需要带""
VERSION_CODE=1
VERSION_NAME=1.0.0
APPLICATION_ID=com.example.properties
APP_NAME=简书
APP_CHANNEL=official
IS_DEBUG=true
build.gradle:
本文例子config.properties是放在根目录下,路径都需要指明,否则编译会报"找不到指定文件"。
// 默认方式-写法1
Properties properties = new Properties()
properties.load(new FileInputStream(rootProject.getRootDir().getAbsolutePath() + "/config.properties"))
println "VERSION_CODE = " + properties.getProperty("VERSION_CODE")//也可以properties["VERSION_CODE"]
println "VERSION_NAME = " + properties.getProperty("VERSION_NAME")//也可以properties["VERSION_NAME"]
println "APPLICATION_ID = " + properties.getProperty("APPLICATION_ID")//也可以properties["APPLICATION_ID"]
println "APP_NAME = " + properties.getProperty("APP_NAME")//也可以properties["APP_NAME"]
println "APP_CHANNEL = " + properties.getProperty("APP_CHANNEL")//也可以properties["APP_CHANNEL"]
println "IS_DEBUG = " + properties.getProperty("IS_DEBUG")//也可以properties["IS_DEBUG"]
// 默认方式-写法2
Properties properties = new Properties()
new File(rootProject.getRootDir().getAbsolutePath() + "/config.properties").withInputStream {
stream -> properties.load(stream)
}
println "VERSION_CODE = " + properties.getProperty("VERSION_CODE")//也可以properties["VERSION_CODE"]
println "VERSION_NAME = " + properties.getProperty("VERSION_NAME")//也可以properties["VERSION_NAME"]
println "APPLICATION_ID = " + properties.getProperty("APPLICATION_ID")//也可以properties["APPLICATION_ID"]
println "APP_NAME = " + properties.getProperty("APP_NAME")//也可以properties["APP_NAME"]
println "APP_CHANNEL = " + properties.getProperty("APP_CHANNEL")//也可以properties["APP_CHANNEL"]
println "IS_DEBUG = " + properties.getProperty("IS_DEBUG")//也可以properties["IS_DEBUG"]
Run:
构建APK文件输出的日志,可以看到输出的结果
2-2、第二种获取方式:
config.properties(新建):
value需要带"",否则获取不了
VERSION_CODE=1
VERSION_NAME="1.0.0"
APPLICATION_ID="com.example.properties"
APP_NAME="简书"
APP_CHANNEL="official"
IS_DEBUG=true
build.gradle:
本文例子config.properties是放在根目录下,路径都需要指明,否则编译会报"找不到指定文件"。
def configSlurper = new ConfigSlurper().parse(new File(rootProject.getRootDir().getAbsolutePath() + "/config.properties").toURL())
println "VERSION_CODE = " + configSlurper.VERSION_CODE
println "VERSION_NAME = " + configSlurper.VERSION_NAME
println "APPLICATION_ID = " + configSlurper.APPLICATION_ID
println "APP_NAME = " + configSlurper.APP_NAME
println "APP_CHANNEL = " + configSlurper.APP_CHANNEL
if (configSlurper.IS_DEBUG) {
println "IS_DEBUG is true"
} else {
println "IS_DEBUG is false"
}
Run:
构建APK文件输出的日志,可以看到输出的结果
四、解决中文乱码
以上汇总情况
情况1:gradle.properties获取数据,会出现中文乱码。
情况2:其他 .properties文件第一种获取方式,会出现中文乱码。(原理其实和1是一致的)
情况3:其他 .properties文件第二种获取方式,没有出现中文乱码。
情况1和情况2的方式,试了UTF-8编码解码之后,得到的还是乱码的,原因就是出在获取的时候就是乱码的,你再怎么编码解码都没用。
因为情况1和情况2都是通过字节流来获取,所以中文都乱码了。。。java基础问题呀!!!
解决方式1(情况1):
如果你的项目一定要使用 gradle.properties,因为情况1字节流的方式不能改,所以可以通过URL编码/解码来实现。
简书 ==>%e7%ae%80%e4%b9%a6【通过UrlEncode编码之后得到】
gradle.properties:
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# 版本号
VERSION_CODE=1
# 版本名称
VERSION_NAME=1.0.0
# 包名
APPLICATION_ID=com.example.properties
# 应用名称
APP_NAME=%e7%ae%80%e4%b9%a6
# 应用渠道
APP_CHANNEL=official
# 是否Debug
IS_DEBUG=true
build.gradle:
最后再通过UrlDecode解码就可以得到:URLDecoder.decode(APP_NAME.toString(), "UTF-8")
println "APP_NAME = " + URLDecoder.decode(APP_NAME.toString(), "UTF-8")
解决方式2(情况2):
如果你的项目使用新建.properties文件,可以把情况2字节流读取改成字符流读取
config.properties(和之前一样):
VERSION_CODE=1
VERSION_NAME=1.0.0
APPLICATION_ID=com.example.properties
APP_NAME=简书
APP_CHANNEL=official
IS_DEBUG=true
build.gradle:
// 默认方式-写法1
Properties properties = new Properties()
properties.load(new InputStreamReader(new FileInputStream(rootProject.getRootDir().getAbsolutePath() + "/config.properties")))
println "VERSION_NAME = " + properties.getProperty("VERSION_NAME")
解决方式3:
情况3就是无乱码