Android知识要点整理(19)----Gradle 之构建变体

构建类型(Build Type)和产品渠道(Product Flavor)的结合,称之为构建变体(Build Variants)。

1.构建类型(Build Type)

构建类型用于定义如何去构建一个APP.每一种类型可以定义是否包含DEBUG信息,applicationId等信息。我们可以在buildTypes代码块下定义构建类型,如下所示:

android {
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile
                ('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

我们可以很容易的创建自定义的构建类型,如下的构建类型定义了app id 后缀和版本名后缀以及API_URL:

android {
    buildTypes {
        //可以继承debug 构建类型
        staging.initWith(buildTypes.debug)
        staging {
            applicationIdSuffix ".staging"
            versionNameSuffix "-staging"
            buildConfigField "String", "API_URL",
                "\"http://staging.example.com/api\""
        }
    }
}

当我们新增一个构建类型时,Gradle 同时会创建新的source set,默认情况下,source set 的目录名和构建名称一致。但是这个目录不会主动被创建,如果需要用到,需要手动去创建它。下面是新增构建类型后的目录结构:

app
└── src
├── debug
│ ├── java
│ │ └── com.package
│ │ └── Constants.java
│ ├── res
│ │ └── layout
│ │ └── activity_main.xml
│ └── AndroidManifest.xml
├── main
│ ├── java
│ │ └── com.package
│ │ └── MainActivity.java
│ ├── res
│ │ ├── drawable
│ │ └── layout
│ │ └── activity_main.xml
│ └── AndroidManifest.xml
├── staging
│ ├── java
│ │ └── com.package
│ │ └── Constants.java
│ ├── res
│ │ └── layout
│ │ └── activity_main.xml
│ └── AndroidManifest.xml
└── release
├── java
│ └── com.package
│ └── Constants.java
└── AndroidManifest.xml

通过修改特定构建目录下的一些资源,可以实现不同的构建结果。但是,需要特别注意的是,java 文件资源是互斥的,就是说在main source set 中存在的java文件,不能在其他构建类型的对应位置存在,否则为提示重复定义;而Resource 文件则不同,在其他构建目录的单一资源文件(比如layout.xml)会覆盖main 目录的单一资源文件,非单一资源文件(比如string.xml,manifest.xml)则会合并在一起。如下示例:
main source set 下的 string.xml:

<resources>
    <string name="app_name">TypesAndFlavors</string>
    <string name="hello_world">Hello world!</string>
</resources>

和 staging source set 下的string.xml

<resources>
    <string name="app_name">TypesAndFlavors STAGING</string>
    <string name="title">Staing</string>
</resources>

合并后的结果如下:

<resources>
    <string name="app_name">TypesAndFlavors STAGING</string>
    <string name="hello_world">Hello world!</string>
    <string name="title">Staing</string>
</resources>

每个构建类型可以有自己的依赖,Gradle 会为每个构建类型自动创建以来配置。比如想要为debug的构建类型单独添加依赖,可以这样做:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.0'
    //针对debug build type 类型的依赖
    debugCompile 'de.mindpipe.android:android-logging-log4j:1.0.3'
}

2.产品渠道(Product Flavor)

构建类型用于定义同一APP的不同构建,产品渠道则用来定义统一APP的不同版本,比如付费版和免费版.通常,如果我们要对外发布不同版本的APP,则我们应该使用Product Flavor来实现,否则就可以使用Build Type.示例代码:

android {
    productFlavors {
        red {
            applicationId 'com.gradleforandroid.red'
            versionCode 3
        }
        blue {
            applicationId 'com.gradleforandroid.blue'
            minSdkVersion 14
            versionCode 4
        }
    }
}

Product Flavor 有不同于Build Type的属性。它和defaultConfigure拥有同样的属性,所以在defaultConfigure中使用的属性都可以在Product Flavor中使用,比如verionCode,versionName等等。
同样的,Gradle 会为每个Product Flavor创建sourceSet目录。

产品渠道可以通过渠道标尺(flavor dimensions)来实现组合渠道,而不同重复定义某些属性。示例如下:

android {
    flavorDimensions "color", "price"

    productFlavors {
        red {
            flavorDimension "color"
        }
        blue {
            flavorDimension "color"
        }
        free {
            flavorDimension "price"
        }
        paid {
            flavorDimension "price"
        }
    }
}

通过定义flavorDimensions,Gradle 会将不同dimensions的product flavoer组合成一个新的product flavor。特别注意的是,一旦定义额了flavorDimensions,就必须在product flavor中使用这些定义的值,否则会编译报错。以上的配置会产生如下的构建:
• blueFreeDebug and blueFreeRelease
• bluePaidDebug and bluePaidRelease
• redFreeDebug and redFreeRelease
• redPaidDebug and redPaidRelease

3.构建变体(Build Variants)

Build Variants 就是 Build Type 和product flavor 的组合结果。上面展示的8中构建结果就是8种构建变体。
Build Variants 同样可以有自己的source set 目录。比如blueFreeDebug 构建变体的source set 目录就是src/blueFreeDebug/java/

不同变体的资源和清单合并有固定的优先级,优先级如下所示:
Build Type >Flavor >Main > Dependencies
比如,如果某个资源同时在Flavor和Main 中定义,那么Flavor中的资源拥有更高的优先级,它会覆盖Main中的资源。
更多的资源合并规则可以看网址t http://tools.android.com/tech-docs/new-buildsystem/user-guide/manifest-merger.

构建变体的配置文件如下:

android {
    buildTypes {
        debug {
            buildConfigField "String", "API_URL",
            "\"http://test.example.com/api\""
        }
        staging.initWith(android.buildTypes.debug)
        staging {
            buildConfigField "String", "API_URL",
            "\"http://staging.example.com/api\""
            applicationIdSuffix ".staging"
        }
    }
    productFlavors {
        red {
            applicationId "com.gradleforandroid.red"
            resValue "color", "flavor_color", "#ff0000"
        }
        blue {
            applicationId "com.gradleforandroid.blue"
            resValue "color", "flavor_color", "#0000ff"
        }
    }
}

虽然定义了很多变体,但是在构建时我们可以过滤掉某些Build Variants。我们可以在顶级build.gradle文件中添加如下代码:

//过滤到blue flavor 和 release build type 组合的variants
android.variantFilter { variant ->
    if(variant.buildType.name.equals('release')) {
        variant.getFlavors().each() { flavor ->
            if (flavor.name.equals('blue')) {
                variant.setIgnore(true);
            }
        }
    }
}

4.签名配置

在构建时我们通常要为各个变体配置签名信息。首先我们可以定义几种类型的签名配置:

android {
    signingConfigs {
        staging.initWith(signingConfigs.debug)
        release {
            storeFile file("release.keystore")
            storePassword"secretpassword"
            keyAlias "gradleforandroid"
            keyPassword "secretpassword"
        }
    }
}

然后为各个变体指定签名配置。通常我们只需要在不同的Build Type 中指定 签名配置就可以了。如下所示:

android {
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

如果不同的Flavor 需要不同的签名信息,可以这么做:

android {
    buildTypes {
        release {
            //为不同的flavor 指定不同的签名配置
            productFlavors.red.signingConfig signingConfigs.red
            productFlavors.blue.signingConfig signingConfigs.blue
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值