Android Gradle 获取properties文件参数 解决中文乱码

一、前言

当我们在Android Studio创建一个工程的时候,都会存在 local.propertiesgradle.properties 两个文件,如下图

项目结构

Properties其实是Java项目中的配置文件,不是Gradle独创的。因为Gradle语法可以和Java进行混合使用,所以在Java项目上面使用Properties文件的方式,在Gradle上面也可以使用。

获取 gradle.properties 的内容不需要我们额外写任何代码,可以直接在build.gradle中进行调用。local.propertiesAndroid 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错误也可以从这里定位

AndroidManifest.xml

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文件输出的日志,可以看到输出的结果

image.png

四、解决中文乱码

以上汇总情况

情况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编码之后得到】

image.png

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就是无乱码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339