android全局配置抽取-gradle.properties

概述

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=测试应用, 无论哪种方式读取出来均是乱码,这是使用过程中遇到的巨大的坑。因此不建议在该文件中使用中文字符。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值