实际项目中,都会应用Android Gradle Plugin,根据实际中的项目模块的职责,可以具体应用如下四种插件类型。

1,apply plugin: 'com.android.application'
实际对应的原型是:com.android.build.gradle.AppExtension,表示此项目模块类型为Android App Module,对应构建生成的文件为.apk类型文件。

2,apply plugin: 'com.android.library'
实际对应的原型是:com.android.build.gradle.LibraryExtension,表示此项目模块类型为Android Library Module,对应构建生成的文件为.arr类型的文件。

3,apply plugin: 'com.android.test'
实际对应的原型是:com.android.build.gradle.TestExtension,表示此项目模块类型为Android test Module,可以在单个模块内通过targetProjectPath指定项目,用于对应项目的单元测试。

4,apply plugin: 'com.android.feature'
实际对应的原型是:com.android.build.gradle.FeatureExtension,表示此项目模块类型为Android feature Module,主要用于单个模块内实现特性,以支持Android Instant Apps

其中,一般项目中最常见的是applicationlibrary插件类型。

项目模块内应用了具体的Android Gradle Plugin类型后,可以开始进行对应的配置,如最常见的如下配置项:

apply plugin: 'com.android.application'

android {
compileSdkVersion 28
defaultConfig {
applicationId "com.happycorn"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
...
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
...
} ...
} dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
...
}
复制代码

此时可以按住CTRL,通过鼠标悬浮,可以看到对应的配置原型信息。

不同的Android Gradle Plugin插件类型,对应不同的实现原型,以及对应可能不同的对外配置项。

同样的,跟踪defaultConfig{}原型信息,可以进入到如下原型说明。

/**
* Specifies defaults for variant properties that the Android plugin applies to all build
* variants.
*
* <p>You can override any <code>defaultConfig</code> property when <a
* href="https://developer.android.com/studio/build/build-variants.html#product-flavors">
* configuring product flavors</a>.
*
* <p>For more information about the properties you can configure in this block, see {@link
* ProductFlavor}.
*/
public void defaultConfig(Action<DefaultConfig> action) {
checkWritability();
action.execute(defaultConfig);
}
复制代码

可见,defaultConfig{}所对应的具体职责是:
为变体属性,指定默认值,Android plugin 可以将指定的变体属性的默认值,应用到所有的变体中。

执行action.execute(defaultConfig);后,将为DefaultConfig对象指定具体的配置。

实际项目开发中,我们往往关注此处有哪些配置项,以及每个配置项对应的含义及作用。

首先可以在Android Gradle DSL文档上对应查询DefaultConfig使用说明。
具体参见:
google.github.io/android-gra…

文档中列出了DefaultConfig对象的对外可配置的属性、方法,以及对应说明,在具体配置时,可能有些需要注意的事项,文档中也做了详尽叙述。

但无论是属性还是方法,一般在build.gradle中配置defaultConfig{}时,一般都是采用形如 key value形式,当然,实际上也可以采用对应的方法原型形式配置,效果是等价的,不过有个前提是,此方法原型是确实存在的,否则,Gradle会报错。
如:

defaultConfig {
...
minSdkVersion 15
...
} 等价于
defaultConfig {
...
minSdkVersion(15)
...
}
复制代码

defaultConfig{}中配置的属性,在构建时,会默认生成对应的变体目录下的BuildConfig.java文件,此文件中将之前配置的属性转变成了对应的JAVA常量形式。

build.gradle中配置如下:

android {
compileSdkVersion 28 defaultConfig {
applicationId "com.happycorn"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
} buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} debug { }
} flavorDimensions "default" productFlavors {
demo {
applicationIdSuffix "demo"
} full {
applicationIdSuffix "full"
}
} }
复制代码

执行./gradlew assembleFull命令,对应生成的BuildConfig文件为:

如其中的buildTypedebug对应的BuildConfig文件内容为:

/**
* Automatically generated file. DO NOT MODIFY
*/
package com.happycorn; public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.happycorn.full";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "full";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0";
}
复制代码

BuildConfig文件为JAVA源码级别,构建时也会对应被编译打包到包中,可以直接在对应的模块中使用。

利用此特性,我们经常可以在项目中对变体环境进行逻辑判断,对应的进行逻辑处理。 如:判断是否是DEBUG,对应的输出Log等。

if (BuildConfig.DEBUG) {
Log.d(TAG, "come here...");
}
复制代码

另外,DefaultConfig对象中专门对外提供了buildConfigField(type, name, value)方法,用于向构建时生成的BuildConfig.java类中增加新的属性。

如:defaultConfig{}中通过buildConfigField(type, name, value)添加如下。

defaultConfig {
...
// 是否打对对用户的内测包
innerTest = project.hasProperty('innertest') ? innertest : 'false'
buildConfigField "boolean", "INNER_TEST", innerTest // 添加模块对应的模块名
buildConfigField "String", "MODULE_NAME", "\"${project.name}\""
}
复制代码

生成的BuildConfig.java中将有对应属性产生。

public final class BuildConfig {
...
// Fields from default config.
public static final boolean INNER_TEST = false;
public static final String MODULE_NAME = "app";
}
复制代码

利用此特性,可以很有技巧性的去处理项目中的一些特定的问题。参照上例代码中的两个追加的属性。
如:
Gradle构建时,通过命令参数-P传入对应参数键值,可以将其在defaultConfig{}中添加,以自动在BuildConfig.java中生成对应属性,然后程序中对应进行一些逻辑的特别处理。

if (BuildConfig.INNER_TEST) {
// 用户内测的一些逻辑处理
...
}
复制代码

又如:
调用项目日志系统时,可以传入对应的模块名,以实现对各个模块的日志过滤展示等。
此时就可以通过project.name取到模块名,追加到BuildConfig.java中。然后调用日志库时可以取用。

CLog.e(BuildConfig.MODULE_NAME, TAG, e)
复制代码

更进一步,此处对各个模块通过defaultConfig{}配置向BuildConfig.java中追加属性可以写成:

allprojects {
...
afterEvaluate { project ->
def android = project.extensions.findByName("android")
if(android != null){
def defaultConfig = android["defaultConfig"]
defaultConfig.buildConfigField("String", "MODULE_NAME", "\"${project.name}\"")
}
}
}
复制代码

使得整体用法显得非常灵活。

除了buildConfigField(type, name, value)方法外,还有一个实用方法resValue(String type, String name, String value)
resValue(String type, String name, String value)等价于向模块res/values中新增一个资源。

如:在buildTypedebug中新增资源:

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} debug {
resValue("string", "app_name_debug", "HappyCornDebug")
resValue("integer", "token", "365")
}
}
复制代码

编译后,对应变体目录结构下会生成资源文件,及对应的资源键值。

项目中对应需要的此资源的地方也可以直接取用:

getResources().getString(R.string.app_name_debug);
getResources().getInteger(R.integer.token);
复制代码

defaultConfig{}中配置的属性与productFlavors中具体Flavor中配置的属性重复时,Android Gradle构建时将以productFlavors中的对应配置为准,可以理解成将defaultConfig{}中对应的配置覆盖掉了。但applicationIdSuffix除外(applicationIdSuffix依然是追加的形式)。

在现实的项目需求中,外部传入的参数键值或通过Gradle/Android Gradle脚本获取的值,结合defaultConfig{}配置,变体,以及对应生成的BuildConfig.java或资源文件,实现一些特定场景下的需求,整体可以非常灵活,且具有一定的技巧性。

作者:HappyCorn
链接:https://juejin.im/post/5c70a1f56fb9a04a0e2dd008
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Android Gradle defaultConfig详解及实用技巧的更多相关文章

  1. Android Studio gradle配置详解

    android gradle配置详解 AppExtension类及其属性 可能大部分人看到AppExtension类会感觉到非常的陌生,其实我们在app中的build.gradle中填写配置信息的时候 ...

  2. Android Studio系列教程五--Gradle命令详解与导入第三方包

    Android Studio系列教程五--Gradle命令详解与导入第三方包 2015 年 01 月 05 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://s ...

  3. Android SDK Manager详解

    Android基础知识——Android SDK Manager详解   做Android开发时,免不了使用Android SDK Manager,安装需要的sdk版本.buildTools版本等等. ...

  4. Android apk签名详解——AS签名、获取签名信息、系统签名、命令行签名

    Apk签名,每一个Android开发者都不陌生.它就是对我们的apk加了一个校验参数,防止apk被掉包.一开始做Android开发,就接触到了apk签名:后来在微信开放平台.高德地图等平台注册时,需要 ...

  5. 《Android游戏开发详解》一1.7 控制流程第1部分——if和else语句

    本节书摘来异步社区<Android游戏开发详解>一书中的第1章,第1.7节,译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区"异步社区"公众号查看. 1.7 ...

  6. android:ToolBar详解

    android:ToolBar详解(手把手教程) 泡在网上的日子 发表于 2014-11-18 12:49 第 124857 次阅读 ToolBar 42 来源 http://blog.mosil.b ...

  7. Android之canvas详解

    首先说一下canvas类: Class Overview The Canvas class holds the "draw" calls. To draw something, y ...

  8. 【转】Android Canvas绘图详解(图文)

    转自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1212/703.html Android Canvas绘图详解(图文) 泡 ...

  9. Android 核心分析 之八Android 启动过程详解

    Android 启动过程详解 Android从Linux系统启动有4个步骤: (1) init进程启动 (2) Native服务启动 (3) System Server,Android服务启动 (4) ...

随机推荐

  1. Asp.Net MVC 中JS通过ajaxfileupload上传图片获取身份证姓名、生日、家庭住址等详细信息

    客户要求用身份证图片上传获取身份证的详细信息就下来研究了一下(现在的客户真的懒 身份证信息都懒得输入了哈哈...),经过慢慢研究,果然皇天不负有心人搞出来了.这个借助的是腾讯的一个SKD  腾讯优图云 ...

  2. Coding theano under remote ubuntu server from local Mac (在本地mac机器上,写、跑、调试、看-远程ubuntu上的theano代码)

    本人是奇葩,最近鼓捣了一套在mac上coding远程ubuntu上的theano代码的东东,记之以期造福后人. Overview: 下图是我的编程环境和网络环境 我期望能在本地mac机器上对远程的ub ...

  3. Intent传值的学习

    今天学习了Intent传值的过程,有点安卓编程经验的都知道,Intent可以实现页面的跳转,可以从一个activity跳转到另一个activity,这个名义上说是界面跳转,其实这句话现在觉得说的很不严 ...

  4. 如何在js或者jquery中操作EL表达式的一个List集合

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 先说明此篇博客看明白了可以干嘛: 就是在js或者jquery中操作一个EL表达式的一个list集合或者复杂类型 ...

  5. Rest接口和Thymeleaf的两个坑

    spring boot thymeleaf 热部署 在使用spring boot 开发的时候,使用了Thymeleaf 作为前端的模板开发,发现在调试过程中,改动了Thymeleaf模板后,需要重新启 ...

  6. Spring Data Jpa 实现分页(Spring MVC+easyui)

    spring data jpa很好的对dao层进行了封装,这篇文章主要来写的是实现easyui datagird数据分页,由于各个UI参数不大一样,所以如果使用的是其他UI,得稍作修改.需要说明的是我 ...

  7. Postman 使用详解

    转自: http://blog.csdn.net/flowerspring/article/details/52774399 Postman 使用详解 阅读 6754收藏 3022016-6-9 作者 ...

  8. 【译】Flink + Kafka 0.11端到端精确一次处理语义的实现

    本文是翻译作品,作者是Piotr Nowojski和Michael Winters.前者是该方案的实现者. 原文地址是https://data-artisans.com/blog/end-to-end ...

  9. 比较集合List<T>集合,前后多了哪些数据,少了哪些数据Except

    1.少了哪些数据 private List<int> GetRoleIdListReduce(List<int> roleIdListOld, List<int> ...

  10. BZOJ_3207_花神的嘲讽计划Ⅰ_哈希+主席树

    BZOJ_3207_花神的嘲讽计划Ⅰ_哈希+主席树 Description 背景 花神是神,一大癖好就是嘲讽大J,举例如下: “哎你傻不傻的![hqz:大笨J]” “这道题又被J屎过了!!” “J这程 ...