Android Gradle defaultConfig详解及实用技巧

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

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

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

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

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

其中,通常项目中最多见的是applicationlibrary插件类型。bash

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

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,经过鼠标悬浮,能够看到对应的配置原型信息。 ide

不一样的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或资源文件,实现一些特定场景下的需求,总体能够很是灵活,且具备必定的技巧性。

相关文章
相关标签/搜索