构建Variant

当开发一个应用时,通常会有几个不同版本。最常见的情况是,你有一个手动测试用于保证质量的测试版本和一个生产版本。这些版本通常有不同的配置。举个例子:测试API和生产API的URL可以不同。除此之外,你的应用可能有一个免费版和一个有额外功能的付费版。在这种情况下,你就需要处理四种不同的版本:免费测试版,付费测试版,免费生产版,付费生产版。不同版本的不同配置让项目变得十分复杂。

在Gradle中,有一些便捷和可扩展的概念可用来定位这些常见问题。前面提到过,每一个有Android Studio常见的新项目都会生成debug和releas构建类型。另外一个概念是product flavor经常结合在一起使用,可以很容易的处理测试和生产的免费和付费版。构建类型和product flavor的结合被称之为构建variant。

构建类型

在Gradle的Android插件中,构建类型通常被用来定义如何构建一个应用或依赖库。每个构建类型都能特殊化,不管debug标示是否被包含,applicationID是什么,无用的资源是否需要被移除等。你可以在buildTypes代码块中定义构建类型。下面是Android Studio创建的构建文件的标准buildTypes代码块:

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

新模块的默认build.gradle文件配置了一个构建类型,叫做release。该构建类型用于禁用无用资源(通过设置minifyEnabled为false)和定义默认ProGuard配置文件的位置。让开发人员更直观的在他们的生产构建上使用ProGuard。

在你的项目中,release构建类型不是被创建的唯一构建类型。默认情况下,每个模块都有一个debug构建类型。其被设置为默认构建类型,但是你可以通过将包含至buildTypes代码块,然后复写任何你想改变的属性来修改其配置。

创建构建类型

当默认的设置不够用时,我们可以很容易的创建自定义构建类型。新的构建类型只需要在buildTypes代码块中新增一个对象即可。例如,下面的staging自定义构建类型:

buildTypes {
        
        staging{
            applicationIdSuffix ".staging"
            versionNameSuffix "-staging"
            buildConfigField "Boolean" "boo" "false"
        }
    }

staging构建类型针对applicationID定义了一个新的后缀,使其和debug以及release版本的applicationID不一样。假设你的构建类型是默认的,并且添加了staging构建类型,那么不同构建类型的applicationID应该像下面这样:

  • Debug:com.package
  • Release: com.package
  • Staging: com.package.staging

这意味着你将能够在相同色设备上同时安装staging版本和release版本,而不发生任何冲突。staging构建类型也有版本名后缀,其在相同设备上区分多个应用版本时非常重要。buildConfigField属性使用一个构建配置变量,为API顶一个一个自定义的属性。

在创建一个新的构建类型时,还可以用另一个构建类型的属性来初始化该构建类型:

buildTypes {

        staging.initWith(buildTypes.debug)
        staging{
            applicationIdSuffix ".staging"
            versionNameSuffix "-staging"
            debuggable = false
        }
    }

initWith()方法创建了一个新的构建类型,并且夫种子了一个已经存在的构建类型的所有属性到新的构建类型中。我们可以通过在新的构建类型对象中简单的定义他们来覆写属性或定义额外的属性。

源集

当创建一个新的构建类型时,Gradle也会创建一个新的源集。源集目录名称默认和构建类型相同。该目录不是在定义的构建类型时自动创建的,因而要在构建类型使用自定义的源码和资源之前,手动创建该源集目录。

你可以针对特定的构建类型覆写某些属性,为某些构建类型添加自定义代码,以及为不同的构建类型添加自定义布局或字符串。

当使用不同的源集时,资源会被一种特殊的方式处理。Drawables和layout文件将会完全覆盖main源集中有相同名称的资源,但是,values文件夹中的文件则不会被覆盖。Gradle将会合并构建类型中的资源到main资源中。

manifest文件与values文件下的文件类同,如果你为一个构建类型创建了一个manifest文件,那么你不必从main源集中拷贝整个manifest文件,只需要添加需要的标签即可。Android插件将会合并manifest。

要创建的源集目录可以在这里查看:
在这里插入图片描述
运行sourceSets任务即可获取

依赖

每个构建类型都可以有自己的依赖。Gradle自动为每个构建类型创建新的依赖配置。如果你只想在debug构建中添加一个logging框架。那么,那可以这样做:

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:28.0.0'
    debugCompile "de.mindpipe.android:android-logging-log4j:1.0.3"
}

你可以以这种方式结合任何构建配置的构建类型,来让依赖变得更加具体。

product flavor

与被用来配置相同APP或library的不同构建类型相反,product flavor被用来创建不同的版本。典型的例子是一个应用有免费版和付费版。另一个常见的情况是,一个计够为多个客户端构建相同功能而品牌不同的应用。这在出租车企业或银行应用中十分常见,一个公司创建一个可以在同一类别所有客户端重复使用的应用。唯一改变的是颜色,图标和后台URL。Product flavors极大的简化了基于相同代码构建多个版本的应用的进程。

如果你不确定十分需要一个新的构建类型或新的produt flavor,那么你应该问自己,十分想要创建一个供内部使用的应用,或一个会发布到Google Play的新APK。如果你需要一个全新的App,独立于你已有的应用发布,那么product flavor就是你需要的,否则,你应该坚持使用构建类型。

创建product flavor

创建Product flavor和创建构建类型类似。你可以通过productFlavor代码块中添加新的Product flavor来创建:

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

product flavor和构建类型相比有不同的属性。这是因为product flavor是ProductFlavor类中的对象,就像存在于所有构建脚本的defaultConfig对象。这就意味着defaultConfig和你的所有prodect flavors享有相同的属性。

源集

和构建类型类似,product flavor 也可以拥有他们自己的源集目录。为一个特殊的flavor创建一个文件夹就和创建一个有flavor名称的文件夹一样简单。你甚至可以为一个特定构建类型和flavor的结合体创建一个文件夹。该文件夹的名称将是flavor名称+构建类型名称。例如,如果你想让blue flavor的release版本有一个不同的应用图标,那么文件夹会被叫做blueRelease。合并文件夹的组成将比构建类型文件夹和product flavor文件夹拥有更高的优先级。

多种定制的版本

在某些情况下,你可能想要更进一步,创建product flavor的结合体。例如,客户A和客户B在他们的APP中都想要免费版和付费版,并且是基于相同代码,不同的品牌。创建四种不同flavor意味着需要像这样设置多个拷贝,所以这不是最佳做法。而使用flavor维度是结合flavor的有效方式,如下:

flavorDimensions "color", "price"

    productFlavors{
        red{
            flavorDimensions "color"
        }
        blue{
            flavorDimensions "color"
        }

        free{
            flavorDimensions "price"
        }
        paid{
            flavorDimensions "price"
        }
    }

当你为flavor添加了维度后,Gradle会希望你能够为每个flavor都添加维度。如果你忘了,那么你会收到一个带有错误接受的构建错误。flavorDemensions数组定义了维度,维度的顺序非常重要。当结合两个flavor时,他们可能定义了相同属性或资源。在这种情况下,flavor维度数组的顺序就决定了哪个flavor配置将被覆盖。在上面的例子中,color维度覆盖了price维度。该吮吸也决定了构建variant的名称。

假设默认的构建配置是debug和release构建类型,那么前面例子中定义的flavor将会生成下main这些构建variant:

  • blueFreeDebug and blueFreeRelease
  • bluePaidDebug and bluePaidRelease
  • redFreeDebug and redFreeRelease
  • redPaidDebug and redPaidRelease

未完。。。

原创文章 63 获赞 59 访问量 4万+

猜你喜欢

转载自blog.csdn.net/u013049016/article/details/91846290