Gradle学习笔记--创建构建变体

1.构建类型(Build types)

Android Studio生成的标准buildTypes块

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

debug构建类型有他自己的默认设置,当我们创建自己的构建类型,会和默认的有些不同,比如 debuggable属性将被设置为true对于debug构建类型,但是其他你创建的类型会被设置为false

1.1创建构建类型

当默认的设置无法满足需求,最简单的方法是创建自定义的构建类型,比如

android {
    buildTypes {
        staging {
            applicationIdSuffix ".staging"
            versionNameSuffix "-staging"
            buildConfigField "String", "API_URL",
            "\"http://staging.example.com/api\""
         }
    }
}

NOTE:要注意的是buildConfigField的第三个参数,不能直接是"“属性值”,不然生成在buildConfig类中的这个自定义属性的值不会有"",从而报错,需要用上面的格式写,或者使用’'括起来,里面写"属性值"。

上面代码定义了新的applicationId的后缀,他可以让你的applicationId不同于其他版本,比如

  1. Debug:com.package
  2. Release: com.package
  3. Staging: com.package.staging

这意味着你可以同时安装不同版本在同一设备上。

当你创建新的构建类型,你不需要每次都重写相同属性,可以复制其他类型的属性来初始化,比如

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

initWith()方法创建了新的构建类型,复制了一个已经存在的构建类型的所有属性到新的里面,想要覆盖或者定义新的属性,只需要在新的构建类型中去定义

1.2 源文件集合(Source sets)

创建新的构建类型,gradle会创建新的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

资源文件会由指定方式被使用在不同源文件集,Drawables和layout文件会完全覆盖main里面同名的源文件(就是直接使用新的文件),但是values下面的文件不会是这样,而是采用合并,比如

//main里面是这样
<resources>
    <string name="app_name">TypesAndFlavors</string>
    <string name="hello_world">Hello world!</string>
</resources>

//自己定义的构建类型目录下的String
<resources>
    <string name="app_name">TypesAndFlavors STAGING</string>
</resources>

//strings.xml会被合并成这样,在你使用staging构建类型
<resources>
    <string name="app_name">TypesAndFlavors STAGING</string>
    <string name="hello_world">Hello world!</string>
</resources>

manifest文件也是这样,你不需要复制整个个manifest,只需要写你需要的部分,最后系统会合并

扫描二维码关注公众号,回复: 6395842 查看本文章
1.3 依赖(Dependencies)

每个构建类型都有自己的依赖集,gradle会自动为每个构建类型创建依赖配置,如果你只需要为debug类型添加logging框架,可以像下面一样

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

2. 产品风味(Product flavors)

产品风味是用于配置同一个app或者library,是用于创建同一个app的不同版本,对于一个之改变了很少的app,比如之改变了logo,url。如果需要一个新的app发布到不同平台,可以用Product flavors,否则可以继续使用build types

感觉就是如果一次要发布多版本,而且不同版本要求更改的东西不多可以用产品风味,如果不需要很多版本,只是测试,正式分开,就可以用build types配置不同构建

2.1 创建产品风味(creating product flavors)
android {
    //现在要求每个产品风味必须属于一个产品维度,下面这句现在不能少
    flovarDimensions 'api','version'
    productFlavors {
        red {
            //指明所属的维度
            dimension 'api'
            applicationId 'com.gradleforandroid.red'
            versionCode 3
        }
        blue {
            dimension 'api'
            applicationId 'com.gradleforandroid.blue'
            minSdkVersion 14
            versionCode 4
        }
        
        yellow {
            dimension 'version'
            applicationId 'com.gradleforandroid.yellow'
            minSdkVersion 14
            versionCode 4
        }
        
        black {
            dimension 'version'
            applicationId 'com.gradleforandroid.black'
            minSdkVersion 14
            versionCode 4
        }
    }
}

最终生成的产品个数等于api维度下的产品数*version下的产品数,这个例子最终产品数是4个,当然这是一种build type下的数量,debug的有4个,release下的有4个,分别是redyellow,redbalck,blueyellow和blueblack

不同维度定义了相同属性,会由先定义的维度覆盖掉后定义的

3.构建变体(build variants)

3.1 Tasks

Android的gradle插件会为每个构建变体创建task

3.3 资源文件和manifest的合并(resource and manifest merging)

android插件会打包源代码集合到app中,库项目也会有额外的resources,我们可能需要申请额外的权限去保存debug变体类型中的log文件,但是正式版请求这个不必要的权限可能会吓走潜在用户,我们应该添加额外的manifest文件到debug构建类型的资源集合中去申明额外权限

资源的优先级(从高到低)

Build type -》 Flavor -> Main ->Dependencies

如果一个resource被声明在flavor和一个main source set中,falvor中的将有更高的优先级,所以flavor source set将被打包,main中的该资源就不会被打包,声明在库项目(library project)中的总是最低优先级

3.4 创建构建变体(creating build variants)
//这和前面内容感觉一样,难道这两种加一块叫做构建变体

//(build type 和 productFlavors)
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"
            }
        }
}
3.5 变体过滤

如果用assemble命令执行会构建所有的变体,如果想要忽略某些变体,可以在app或库项目的(也就是module级别的)顶级build.gradle中配置

android.variantFilter { variant ->
    if(variant.buildType.name.equals('release')) {
        variant.getFlavors().each() {flavor ->
            if (flavor.name.equals('blue')) {
                variant.setIgnore(true);
            }
        }
    }
}
3.6 签名配置(signing configurations)

发布应用的时候需要为不同的构建类型使用同的签名key,可以使用签名配置

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

系统为debug类型自动创建了默认签名配置,我们不需要单独创建

当你定义了signing configurations,需要把他们应用到build types或flavors中,build types和flavors都有一个属性叫做signingConfig

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

在flavor中,也是相同的

android {
    productFlavors {
        blue {
            signingConfig signingConfigs.release
        }
    }
}

这种用法会导致错误,当你分配一个配置给一种风味,实际上是覆盖了build type的配置(这样这个风味下的debug类型的build type的签名也会被覆盖成release的签名),如果你想要每个风味的不同build type都有不同的KEY,可以如下配置,这样就不会影响debug或其他构建类型的签名

android {
    buildTypes {
        release {
            productFlavors.red.signingConfig signingConfigs.red
            productFlavors.blue.signingConfig signingConfigs.blue
            //这样设置,就只会影响release
        }
    }
}

如果按照之前的配置,blue风味的debug和release都会使用signingConfig.release的配置,现在这样,就会设置开发版用release

猜你喜欢

转载自blog.csdn.net/One_Month/article/details/88167546