概述
android工程中有一个非常重要的文件-gradle.properties,它主要用于存储一些全局性配置,例如 jvm 的配置等,除此之外,业务层面的配置也可以抽取出来放在此处,方便各个module调用。
默认的 gradle.properties
长这样:
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
如上格式的内容是典型的 ini
格式的文件,配置项通过回车符
来分割。
使用场景
为支持自动化编译android工程,我们需要把配置集中起来,方便动态替换,有如下要求需要满足:
1. 应用Id 可以配置 (对应 build.gradle => applicationId)
2. 应用版本 VersionName 和 VersionCode 可以配置 (对应 build.gradle => versionCode | versionName)
3. 应用名称 Name 可以配置 (对应 AndroidManifest.xml => android:label,这里有坑,请往下看)
4. 百度定位Key 可以配置 (对应 AndroidManifest.xml => meta-data)
5. 启动页面 可以配置 ( 对应 MainActivity.java => 变量)
将如上需要配置的地方抽取出来到统一的地方,那就是gradle.properties
文件。
写入配置
在gradle.properties
文件中,配置如下:
AppID=com.gz.debugtool
AppVersionName=1.0
AppVersionCode=1
StartPage=index.html
BaiduKey=u91cPvSUevIzvOhBdBGU7iv5mSb6mHDs
build.gradle文件中读配置
想要在build.gradle 中读取配置,直接 project.keyName
即可,例如 应用Id 和应用版本的配置如下:
defaultConfig {
applicationId project.AppID //读取应用Id
minSdkVersion 19
targetSdkVersion 25
versionCode project.AppVersionCode as int //读取版本号 转换成数字
versionName project.AppVersionName //读取版本名称
}
AndroidManifest.xml中读配置
在Manifest读取配置,其实是 Gradle 替换文本的过程,也就是在 Build 阶段会动态替换 该文件中的占位符。例如 BaiduKey 的配置替换:
在 build.gradle => buildTypes 中先定义需要替换的Key,使用manifestPlaceholders
字段:
buildTypes {
release {
manifestPlaceholders = [BAIDU_APPKEY_VALUE: BaiduKey]
//...
}
debug {
manifestPlaceholders = [BAIDU_APPKEY_VALUE: BaiduKey]
//...
}
}
然后,在AndroidManifest.xml中这样使用:
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="${BAIDU_APPKEY_VALUE}" >
</meta-data>
对于manifestPlaceholders的配置,实际是可以有多个的(通过逗号隔开),可以这样写:
manifestPlaceholders = [
BAIDU_APPKEY_VALUE: BaiduKey,
Key1: Value1,
Key2: Value2
]
来看看底层源码,发现 manifestPlaceHolders 接收 Map 类型的参数,上述配置多个,使用[
可能会让开发者诧异,这只是gradle的语法问题(我们可能习惯来使用 { }
)。
public void setManifestPlaceholders(Map<String,Object> manifestPlaceholders){
this.mManifestPlaceholders.clear();
this.mManifestPlaceholders.putAll(manifestPlaceholders);
//...
}
MainActivity.java中读取配置
在java代码中读取配置,其实是动态编译的过程,它会先在 BuildConfig.java
中生成对应的静态变量, 而后在java代码中才能引用。
在 build.gradle => buildTypes 中先定义需要生成静态变量的的Key ,使用 buildConfigField
定义字段类型type、字段name以及具体的value(指向gradle.properties的key)
buildTypes {
release {
buildConfigField "String", "StartPage", "\"${StartPage}\""
//...
}
debug {
buildConfigField "String", "StartPage", "\"${StartPage}\""
//...
}
}
经过Gradle Sync
后,可以在BuildConfig.java
中看到自动生成的代码:
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.gz.debugtool";
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: debug
public static final String StartPage = "index.html"; //这里是自动生成的静态变量
}
在MainActivity.java中使用如下:
String startPage = BuildConfig.StartPage;
来看看底层源码,该方法接收三个参数, type、name、value
public void buildConfigField(@NonNull String type,@NonNull String name,@NonNull String value) {
ClassField alreadyPresent = getBuildConfigFields().get(name);
if (alreadyPresent != null) {
logger.info(
"BuildType(${getName()}): buildConfigField '$name' value is being replaced: ${alreadyPresent.value} -> $value");
}
addBuildConfigField(AndroidBuilder.createClassField(type, name, value));
}
中文乱码问题
gradle.properties 中配置中文,例如AppName=测试应用, 无论哪种方式读取出来均是乱码,这是使用过程中遇到的巨大的坑。因此不建议在该文件中使用中文字符。