看完这篇你学到什么:php
通常咱们开发的环境分为:debug 和 release,可是你想再份内测1环境、内测2环境等等怎么办呢?html
这就须要依赖强大的gradle 来配置了。java
相关的配置也能够参考谷歌官方文档。android
buildTypes
*名词解析:*咱们一般会分不一样的编译环境进行打包,好比有debug、release、beta等环境参数,像这种咱们就称之为buildTypes.git
您能够在模块级 build.gradle
文件的 android {}
代码块内部建立和配置构建类型。当您建立新模块时,Android Studio 会自动为您建立调试和发布这两种构建类型。尽管调试构建类型不会出如今构建配置文件中,Android Studio 会将其配置为 debuggable true
。这样,您能够在安全的 Android 设备上调试应用并使用通用调试密钥库配置 APK 签署。github
若是您但愿添加或更改特定设置,您能够将调试构建类型添加到您的配置中。如下示例为调试构建类型指定了 applicationIdSuffix
,并配置了一个使用调试构建类型中的设置进行初始化的jnidebug
构建类型。api
applicationIdSuffix:
字段表示,在不改变你默认的程序ID(包名)的状况下,为其添加后缀。好比你的包名是com.rae.app
,但你想区分测试包和正式包的状况,这个时候将applicationIdSuffix
设置为.debug
,那么你的应用程序对应的包名就变成了com.rae.app.debug
安全
android {
...
defaultConfig {...}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
applicationIdSuffix ".debug"
}
/** * The 'initWith' property allows you to copy configurations from other build types, * so you don't have to configure one from the beginning. You can then configure * just the settings you want to change. The following line initializes * 'jnidebug' using the debug build type, and changes only the * applicationIdSuffix and versionNameSuffix settings. */
jnidebug {
// This copies the debuggable attribute and debug signing configurations.
initWith debug
applicationIdSuffix ".jnidebug"
jniDebuggable true
}
}
}
复制代码
名词解析: 一般源代码是放在src/main
文件夹下的,但你想能够根据不一样的构建类型(好比debug、release)区分不一样的源文件,这样对应创建的文件夹就是一个不一样的构建源。打个比方,debug的构建源为src/debug
,release的构建源为src/release
,而在src/main
定义的为公共资源,最后在构建的时候会进行合并操做。app
更多参考官网文档。ide
Android Studio 按逻辑关系将每一个模块的源代码和资源分组为源集。模块的 main/ 源集包括其全部构建变体共用的代码和资源。其余源集目录为可选项,在您配置新的构建变体时,Android Studio 不会自动为您建立这些目录。不过,建立相似于 main/ 的源集有助于让 Gradle 只应在构建特定应用版本时使用的文件和资源井井有理:
构建源的命名规则以下:
productFlavor
表示渠道包,能够看下面的多渠道打包
src/main/
此源集包括全部构建变体共用的代码和资源。
src/<buildType>
/ 建立此源集可加入特定构建类型专用的代码和资源。示例:src/jnidebug
src/<productFlavor>
/ 建立此源集可加入特定产品风味专用的代码和资源。好比百度渠道包:src/baidu
src/<productFlavorBuildType>
/ 建立此源集可加入特定构建变体专用的代码和资源。
例如,要生成应用的“彻底调试”版本,构建系统须要合并来自如下源集的代码、设置和资源。好比:百度的开发环境包:src/baiduDebug
不少时候咱们会把sdk或者api接口单独作成一个库,通常会有生产环境和测试环境之分,但在依赖的时候每每咱们会像这样去引用:compile project(':sdk')
,这样依赖的环境就是release
,在开发调试的时候测试环境的时候就不行了。咱们得换另一种方式:
<buildType>
Compile project()
这样会根据不一样的构建类型去依赖不一样的包,好比咱们测试环境的依赖包:debugCompile project(':sdk')
,再好比上面的jnidebug
:jnidebugCompile project(':sdk')
那么问题来了,我当前的构建类型怎么对应到其余的module
去呢?好比你的app要依赖sdk module 的debug 环境,那么你能够这么作:
configuration
:目标module
的<buildType>
,好比你sdk 中<buildType>
的debug
构建类型
debugCompile project(path: ':sdk', configuration: 'debug')
一、先看app这边的build.gradle
配置:
apply plugin: 'com.android.application'
android {
buildTypes {
release {
minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug {
applicationIdSuffix '.debug'
minifyEnabled false
}
// 自定义的构建类型,名字随便取,必定要有意义
raedebug {
initWith debug
applicationIdSuffix '.raedebug'
}
}
}
dependencies {
// 生成环境依赖
releaseCompile project(path: ':sdk', configuration: 'release') // 测试环境依赖 debugCompile project(path: ':sdk', configuration: 'debug') // 自定义构建类型依赖 raedebugCompile project(path: ':sdk', configuration: 'uutest') } 复制代码
二、sdk module的build.gradle
配置:
apply plugin: 'com.android.library'
android {
buildTypes {
debug {
debuggable true
minifyEnabled false
}
release {
minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } // 注意这里,跟第一点的 raedebugCompile project的configuration要匹配。 uutest {
initWith debug
}
}
}
复制代码
productFlavors
先看看build.gradle
配置你就懂了
android{
// 渠道包定义,默认定义的名称就是渠道名称
productFlavors {
dev {} // 测试
baidu {} // 百度手机助手
yinyongbao {} // 应用宝
m360 {} // 360手机助手
pp {} // PP助手
anzhi{} // 安智市场
xiaomi {} // 小米商店
letv {} // 乐视商店
huawei {} // 华为商店
lenovomm {} // 联想乐商店
other {} // 其余市场
official{} // 官方版本
}
// 批量渠道包值替换
productFlavors.all { flavor ->
// 友盟、极光推送渠道包, UMENG_CHANNEL 是根据你AndroidManifest.xml来配置的,请看下面。
flavor.manifestPlaceholders = [UMENG_CHANNEL: name, JPUSH_CHANNEL: name]
}
}
复制代码
AndroidManifest.xml
配置:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.rae.demo">
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme">
<!--变量采用${变量名}这样来替换,不只限与<meta-data /> 标签,任何你想替换的都行。-->
<meta-data android:name="UMENG_APPKEY" android:value="${UMENG_APPKEY}"/>
<meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL}"/>
<!--${变量随变换}-->
<activity android:name=".DemoActivity" android:label="${变量随变换}"/>
</application>
</manifest>
复制代码
sync gradle以后看看gradle projects 面板列表就多出了好到渠道的任务了,Build Variants 面板也相对应多了这些构建类型。
在结合到多渠道打包后,运营的那边但愿咱们给的渠道包是这种格式的app-{版本号}-{渠道名称}.apk
,那咱们来看看怎么来知足这个多渠道打包输出apk文件名修改的。
android{
// 输出文件配置
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith('.apk')) {
def dirName = outputFile.parent // 输出文件夹所在的位置
// 文件名修改
def fileName = "app-${output.processResources.variantName}-${defaultConfig.versionName}-${variant.flavorName}.apk"
// 好比不想这么麻烦,直接在后面加上版本号也行:
// def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}.apk")
output.outputFile = new File(dirName, fileName)
}
}
}
}
复制代码
上面介绍的多渠道打包是采用gralde默认的配置,但有个弊端是每一个渠道包都会从新编译一次,编译速度慢。对大量的多渠道打包推荐用美团的walle
,项目地址:github.com/Meituan-Dia…