一稽穆、前言
當(dāng)我們在Android Studio創(chuàng)建一個工程的時候拇泛,都會存在 local.properties 和 gradle.properties 兩個文件卑雁,如下圖
Properties其實是Java項目中的配置文件凳怨,不是Gradle獨創(chuàng)的叉讥。因為Gradle語法可以和Java進行混合使用,所以在Java項目上面使用Properties文件的方式芯杀,在Gradle上面也可以使用端考。
獲取 gradle.properties 的內(nèi)容不需要我們額外寫任何代碼,可以直接在build.gradle中進行調(diào)用瘪匿。local.properties 是 Android Studio 配置SDK和NDK一些路徑跛梗,還不可以直接調(diào)用。
二棋弥、Properties
了解Properties,其實最主要是了解它的數(shù)據(jù)格式诚欠。Properties
數(shù)據(jù)格式以鍵值對的方式:key=value
"#"作為注釋使用
三顽染、Gradle中使用properties
1、gradle.properties
因為 Gradle 內(nèi)置了對 gradle.properties 的調(diào)用方式轰绵,所以 build.gradle 可以直接獲取 gradle.properties 中的內(nèi)容粉寞。
需要注意的是 gradle.properties 中的value是都不需要帶 "" ,Gradle 會先把值轉(zhuǎn)換為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
# 應(yīng)用名稱
APP_NAME=簡書
# 應(yīng)用渠道
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:
構(gòu)建APK文件輸出的日志唧垦,可以看到輸出的結(jié)果
也可以通過AndroidManifest.xml實時查看,點擊Merged Mainfest:
這里可能很多人都不知道液样,AndroidManifest.xml 中出現(xiàn)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:
構(gòu)建APK文件輸出的日志澎怒,可以看到輸出的結(jié)果
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:
構(gòu)建APK文件輸出的日志,可以看到輸出的結(jié)果
四琳状、解決中文亂碼
以上匯總情況
情況1:gradle.properties獲取數(shù)據(jù)磕瓷,會出現(xiàn)中文亂碼。
情況2:其他 .properties文件第一種獲取方式算撮,會出現(xiàn)中文亂碼生宛。(原理其實和1是一致的)
情況3:其他 .properties文件第二種獲取方式,沒有出現(xiàn)中文亂碼肮柜。
情況1和情況2的方式陷舅,試了UTF-8編碼解碼之后,得到的還是亂碼的审洞,原因就是出在獲取的時候就是亂碼的莱睁,你再怎么編碼解碼都沒用。
因為情況1和情況2都是通過字節(jié)流來獲取芒澜,所以中文都亂碼了仰剿。。痴晦。java基礎(chǔ)問題呀D纤薄!誊酌!
解決方式1(情況1):
如果你的項目一定要使用 gradle.properties部凑,因為情況1字節(jié)流的方式不能改,所以可以通過URL編碼/解碼來實現(xiàn)碧浊。
簡書 ==>%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
# 應(yīng)用名稱
APP_NAME=%e7%ae%80%e4%b9%a6
# 應(yīng)用渠道
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字節(jié)流讀取改成字符流讀取
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就是無亂碼