Android Gradle 进阶配置指南,太爽了
defaultConfig:设置一些默认属性,其可用属性是 buildTypes(debug,release,其他+)和 productFlavors(谷歌商店,豌豆荚,小米应用商店)之和。最终可以打出的 APK 的数量就是 buildTypes 乘以 productFlavors。构建的变量名称是 productFlavors+buildTypes。
dependencies 配置依赖:各种外部依赖直接一行代码搞定,不用手动下依赖包了。其中 compile fileTree(dir: 'libs', include: ['*.jar'])的意思是依赖 libs 目录下全部的 jar 文件。
buildscript {repositories {google()jcenter()mavenCentral()}dependencies {classpath 'com.android.tools.build:gradle:3.2.1'}}
buildscript 节点,大概意思就是支持 maven,google,声明 Gradle 的版本.如果用到一些其他插件也需要在此申明.
signingConfigs {myConfig {storeFile file("xxx.keystore")storePassword "123123"keyAlias "xxx"keyPassword "123123"v2SigningEnabled true}}
buildTypes{release {//应用 myConfigsigningConfig signingConfigs.myConfigminifyEnabled trueproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'}}
签名配置:storeFile : keystore 文件 storePassword : 密码 keyAlias : 别名 keyPassword : 别名密码 v2SigningEnabled : 启用 V2 签名方案 minifyEnabled : 是否开启混淆 shrinkResources : 是否移除无用资源文件,shrinkResources 依赖于 minifyEnabled,必须和 minifyEnabled 一起用
以上只是最简单的 gradle 配置,实际项目中我们的 app 会很复杂,比如不仅引用到一些 jar 文件,也可能会引用一些 Android Library 项目以及一些.so 文件,而且实际发布的时候我们可能不仅需要发布到一个平台上,目前 Android 大大小小可能得十几个平台,Gradle 通过一些其他的配置都可以解决。顺便说下 Gradle 是 Google 大力支持的。
进阶配置
配置 manifest 变量
很多第三方 SDK 需要在 AndroidManifest.xml 中配置你的一些 key 信息,以融云为例,测试包和正式包的 key 是不同的,那么就可
以这么写::
<meta-dataandroid:name="RONG_CLOUD_APP_KEY"android:value="${rongKey}" />
然后在 productFlavors 中的各个版本中加上不同的信息,这样你打出的不同包采用的 appkey 也会不一样。
manifestPlaceholders = [rongKey: "8luwapkv8jrrl"]
代码中读取变量
有时候我们想根据不同的版本,设置相同变量不同的值,最常见的使用场景就是 Log 工具类,通过设置 isDubug 不同值判断是否打印日志.其他还包括获取包名,获取渠道名
buildConfigField "String", "PlatformSource", ""Google""buildConfigField "String", "showProjName", ""TestProj""
最后调用 : BuildConfig.PlatformSource
public final class BuildConfig {public static final boolean DEBUG = Boolean.parseBoolean("true");public static final String APPLICATION_ID = "com.xxx.xxxx";public static final String BUILD_TYPE = "debug";public static final String PlatformSource = "Google";public static final String showProjName = "TestProj";
上面的是加在 defaultConfig 中的,而加在 buildTypes 或 productFlavors 中就会在不同构建版本出现不同的值。如果再配置上不同的 applicationId,那么就可以在同一个手机上同时安装不同构建版本的应用。
productFlavors {//国内版本 china{applicationId "com.shy.china"versionCode "2.0.0"versionName "30"}//韩国版本 korea{applicationId "com.shy.korea"versionCode "1.0.0"versionName "1"}}
到这里你会发现 buildTypes 和 productFlavors 定义很相似,不过他们的差别在:
buildType 不会改变应用程序的代码,它们只是处理的东西不同,你可以通过 buildType 来获取更多的技术细节(例如:build optimization,log level minifyEnabled 等等),但是 app 的内容不会改变.
productFlavor 配置可以改变 app 的内容(可以设想成 package 理解,buildType 没法改 applicationId).
BuildVariants 变体
buildTypes+productFlavors 相结合,组成构建变体,buildTypes 构建类型,主要就是 debug(测试),pre(预发布) ,release(线上)的分别。productFlavors 产品口味,主要就是各种渠道版本。两个合体就会构建出不同的版本 apk (总 apk 个数=构建类型个数*渠道个数).看图:
buildTypes 构建类型
buildTypes {release {multiDexKeepProguard file('multidex-config.pro')minifyEnabled true//是否开启混淆(上线)shrinkResources trueproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}debug {multiDexKeepProguard file('multidex-config.pro')minifyEnabled false//是否开启混淆(上线)proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}
productFlavors 多维度
当需要从多个维度区分 app 版本,比如是否付费和渠道时,就需要使用 flavorDimensions 来区分
flavorDimensions "channel", "env"
productFlavors {china {dimension "channel"applicationId "com.shy.china"versionCode project.CHINA_VERSION_CODE as intversionName project.CHINA_VERSION_NAMEsigningConfig signingConfigs.china
buildConfigField "String", "PlatformSource", ""china""buildConfigField "String", "showProjName", ""projName_china""
manifestPlaceholders = [package_name : applicationId,JPUSH_PKGNAME: applicationId,JPUSH_APPKEY : "xxxxxxxxxxxx", //JPush 上注册的包名对应的 appkey.JPUSH_CHANNEL: "developer-default", //暂时填写默认值即可.]}
korea {dimension "channel"applicationId "com.shy.korea"
versionCode project.KOREA_VERSION_CODE as intversionName project.KOREA_VERSION_NAMEsigningConfig signingConfigs.korea
manifestPlaceholders = [package_name : applicationId,JPUSH_PKGNAME: applicationId,JPUSH_APPKEY : "xxxxxxx", //JPush 上注册的包名对应的 appkey.JPUSH_CHANNEL: "developer-default", //暂时填写默认值即可.]
buildConfigField "String", "PlatformSource", ""korea""buildConfigField "String", "showProjName", ""projName_korea""}
dev {dimension "env"}pre {dimension "env"}produce {dimension "env"}}
此时在 build 一下 , BuildVariants 中会生成 12 种变体(总 apk 个数=构建类型个数_渠道个数_维度个数) :
chinaDevDebug(常用)
chinaDevRelease
chinaPreDebug
chinaPreRelease(常用)
chinaProduceDebug
chinaProduceRelease(常用)
koreaDevDebug(常用)
koreaDevRelease
koreaPreDebug
koreaPreRelease(常用)
koreaProduceDebug
koreaProduceRelease(常用)
注意!warning:
1.当添加了 flavorDimensions,必须为每个 productFlavors 添加 dimension,否则会提示错误
2.在 gradle:3.0.0 以上,在 build.gradle 里必须要有 flavorDimensions 字段,哪怕只有一个维度也要声明,否则报错
打包
一次生成所有渠道包 打开命令行窗口,进入到工程的根目录下,输入
gradle assembleChinaProduceRelease
其他技巧
1.Gradle task
Gradle task 适合用来完成一些既繁琐又容易出错的重复性手工作,比如批量修改,复制,重命名文件。 比如 applicationVariants.all 这个 task 可以针对每个构建版本设置各种属性,比如修改每个构建版本生成的 apk 名字:
applicationVariants.all { variant ->variant.outputs.each { output ->output.outputFile = new File(new File("{flavorName}-{buildType}-v{buildTime}.apk)}}
2.Moudle 动态依赖
在组件化 app 里面,我们可能在测试包和正式包需要依赖不同组件。比如测试环境需要调试模块,但正式环境不需要。假如 productFlavors 如下,调试模块名字为 module-test
productFlavors {test{}publish{}}
那么在 dependencies 里面就可以这么依赖 test 模块:
ceshiCompile project(':module-test')
同样 buildTypes 也是适用的,两者可以一起或单独使用:
评论