Android Studio六--Gradle多渠道打包
来源:互联网 发布:尼古拉的遗嘱 知乎 编辑:程序博客网 时间:2024/05/24 04:37
由于国内Android市场众多渠道,为了统计每个渠道的下载及其它数据统计,就需要我们针对每个渠道单独打包,如果让你打几十个市场的包岂不烦死了,不过有了Gradle,这再也不是事了。
友盟多渠道打包
废话不多说,以友盟统计为例,在AndroidManifest.xml里面会有这么一段:
<meta-data android:name="UMENG_CHANNEL" android:value="Channel_ID" />
里面的Channel_ID就是渠道标示。我们的目标就是在编译的时候这个值能够自动变化。
- 第一步 在AndroidManifest.xml里配置PlaceHolder
<meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL_VALUE}" />
- 第二步 在build.gradle设置productFlavors
android { productFlavors { xiaomi { manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"] } _360 { manifestPlaceholders = [UMENG_CHANNEL_VALUE: "_360"] } baidu { manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"] } wandoujia { manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"] } } }
或者批量修改
android { productFlavors { xiaomi {} _360 {} baidu {} wandoujia {} } productFlavors.all { flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name] }}
很简单清晰有没有?直接执行 ./gradlew assembleRelease , 然后就可以静静的喝杯咖啡等待打包完成吧。
assemble结合Build Variants来创建task
上一篇博客介绍了 assemble 这个命令,会结合 Build Type 创建自己的task,如:
./gradlew assembleDebug
./gradlew assembleRelease
除此之外 assemble 还能和 Product Flavor 结合创建新的任务,其实 assemble 是和 Build Variants 一起结合使用的,而 Build Variants = Build Type + Product Flavor , 举个例子大家就明白了:
如果我们想打包wandoujia渠道的release版本,执行如下命令就好了:
- ./gradlew assembleWandoujiaRelease
如果我们只打wandoujia渠道版本,则:
- ./gradlew assembleWandoujia
此命令会生成wandoujia渠道的Release和Debug版本
同理我想打全部Release版本:
- ./gradlew assembleRelease
这条命令会把Product Flavor下的所有渠道的Release版本都打出来。
总之,assemble 命令创建task有如下用法:
**assemble**: 允许直接构建一个Variant版本,例如assembleFlavor1Debug。
**assemble**: 允许构建指定Build Type的所有APK,例如assembleDebug将会构建Flavor1Debug和Flavor2Debug两个Variant版本。
**assemble**: 允许构建指定flavor的所有APK,例如assembleFlavor1将会构建Flavor1Debug和Flavor1Release两个Variant版本。
完整的gradle脚本
最后福利大放送,来一份我在项目中使用的完整的gradle文件配置:
apply plugin: 'com.android.application'def releaseTime() { return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))}android { compileSdkVersion 21 buildToolsVersion '21.1.2' defaultConfig { applicationId "com.boohee.*" minSdkVersion 14 targetSdkVersion 21 versionCode 1 versionName "1.0" // dex突破65535的限制 multiDexEnabled true // 默认是umeng的渠道 manifestPlaceholders = [UMENG_CHANNEL_VALUE: "umeng"] } lintOptions { abortOnError false } signingConfigs { debug { // No debug config } release { storeFile file("../yourapp.keystore") storePassword "your password" keyAlias "your alias" keyPassword "your password" } } buildTypes { debug { // 显示Log buildConfigField "boolean", "LOG_DEBUG", "true" versionNameSuffix "-debug" minifyEnabled false zipAlignEnabled false shrinkResources false signingConfig signingConfigs.debug } release { // 不显示Log buildConfigField "boolean", "LOG_DEBUG", "false" minifyEnabled true zipAlignEnabled true // 移除无用的resource文件 shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release applicationVariants.all { variant -> variant.outputs.each { output -> def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith('.apk')) { // 输出apk名称为boohee_v1.0_2015-01-15_wandoujia.apk def fileName = "boohee_v${defaultConfig.versionName}_${releaseTime()}_${variant.productFlavors[0].name}.apk" output.outputFile = new File(outputFile.parent, fileName) } } } } } // 友盟多渠道打包 productFlavors { wandoujia {} _360 {} baidu {} xiaomi {} tencent {} taobao {} ... } productFlavors.all { flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name] }}dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:support-v4:21.0.3' compile 'com.jakewharton:butterknife:6.0.0' ...}
美团Android自动化之旅—适配渠道包
概述
前一篇文章(美团Android自动化之旅—生成渠道包)介绍了Android中几种生成渠道包的方式,基本解决了打包慢的问题。
但是,随着渠道越来越多,不同渠道对应用的要求也不尽相同。例如,有的渠道要求美团客户端的应用名为美团
,有的渠道要求应用名为美团团购
。又比如,有些渠道要求应用不能使用第三方统计工具(如flurry)。总之,每次打包都需要对这些渠道进行适配。
之前的做法是为每个需要适配的渠道创建一个Git分支,发版时再切换到相应的分支,并合并主分支的代码。适配的渠道比较少的话这种方式还可以接受,如果分支比较多,对开发人员来说简直就是噩梦。还好,自从有了Gradle flavor,一切都变得简单了。本文假定读者使用过Gradle,如果还不了解建议先阅读相关文档。
Flavor
先来看build.gradle
文件中的一段代码:
android { .... productFlavors { flavor1 { minSdkVersion 14 } }}
上例定义了一个flavor:flavor1
,并指定了应用的minSdkVersion
为14(当然还可以配置更多的属性,具体可参考相关文档)。与此同时,Gradle还会为该flavor关联对应的sourceSet
,默认位置为src/<flavorName>
目录,对应到本例就是src/flavor1
。
接下来,要做的就是根据具体的需求在build.gradle
文件中配置flavor,并添加必要的代码和资源文件。以flavor1
为例,运行gradle assembleFlavor1
命令既可生成所需的适配包。下面主要介绍美团团购Android客户端的一些适配案例。
案例
使用不同的包名
美团团购Android客户端之前有两个版本:手机版(com.meituan.group
)和hd版(com.meituan.group.hd
),两个版本使用了不同的代码。目前hd版对应的代码已不再维护,希望能直接使用手机版的代码。解决该问题可以有多种方法,不过使用flavor相对比较简单,示例如下:
productFlavors { hd { applicationId "com.meituan.group.hd" }}
上面的代码添加了一个名为hd
的flavor,并指定了应用的包名为com.meituan.group.hd
,运行gradle assembleHd
命令即可生成hd适配包。
控制是否自动更新
美团团购Android客户端在启动时会默认检查客户端是否有更新,如果有更新就会提示用户下载。但是有些渠道和应用市场不允许这种默认行为,所以在适配这些渠道时需要禁止自动更新功能。
解决的思路是提供一个配置字段,应用启动的时候检查该字段的值以决定是否开启自动更新功能。使用flavor可以完美的解决这类问题。
Gradle会在generateSources
阶段为flavor生成一个BuildConfig.java
文件。BuildConfig
类默认提供了一些常量字段,比如应用的版本名(VERSION_NAME
),应用的包名(PACKAGE_NAME
)等。更强大的是,开发者还可以添加自定义的一些字段。下面的示例假设wandoujia
市场默认禁止自动更新功能:
android { defaultConfig { buildConfigField "boolean", "AUTO_UPDATES", "true" } productFlavors { wandoujia { buildConfigField "boolean", "AUTO_UPDATES", "false" } }}
上面的代码会在BuildConfig
类中生成AUTO_UPDATES
布尔常量,默认值为true
,在使用wandoujia
flavor时,该值会被设置成false
。接下来就可以在代码中使用AUTO_UPDATES
常量来判断是否开启自动更新功能了。最后,运行gradle assembleWandoujia
命令即可生成默认不开启自动升级功能的渠道包,是不是很简单。
使用不同的应用名
最常见的一类适配是修改应用的资源。例如,美团团购Android客户端的应用名是美团
,但有的渠道需要把应用名修改为美团团购
;还有,客户端经常会和一些应用分发市场合作,需要在应用的启动界面中加上第三方市场的Logo,类似这类适配形式还有很多。
Gradle在构建应用时,会优先使用flavor所属dataSet
中的同名资源。所以,解决思路就是在flavor的dataSet
中添加同名的字符串资源,以覆盖默认的资源。下面以适配wandoujia
渠道的应用名为美团团购
为例进行介绍。
首先,在build.gradle
配置文件中添加如下flavor:
android { productFlavors { wandoujia { } }}
上面的配置会默认src/wandoujia
目录为wandoujia
flavor的dataSet
。
接下来,在src
目录内创建wandoujia
目录,并添加如下应用名字符串资源(src/wandoujia/res/values/appname.xml
):
<resources> <string name="app_name">美团团购</string></resources>
默认的应用名字符串资源如下(src/main/res/values/strings.xml
):
<resources> <string name="app_name">美团</string></resources>
最后,运行gradle assembleWandoujia
命令即可生成应用名为美团团购
的应用了。
使用第三方SDK
某些渠道会要求客户端嵌入第三方SDK来满足特定的适配需求。比如360应用市场要求美团团购Android客户端的精品应用
模块使用他们提供的SDK。问题的难点在于如何只为特定的渠道添加SDK,其他渠道不引入该SDK。使用flavor可以很好的解决这个问题,下面以为qihu360
flavor引入com.qihoo360.union.sdk:union:1.0
SDK为例进行说明:
android { productFlavors { qihu360 { } }}...dependencies { provided 'com.qihoo360.union.sdk:union:1.0' qihu360Compile 'com.qihoo360.union.sdk:union:1.0'}
上例添加了名为qihu360
的flavor,并且指定编译和运行时都依赖com.qihoo360.union.sdk:union:1.0
。而其他渠道只是在构建的时候依赖该SDK,打包的时候并不会添加它。
接下来,需要在代码中使用反射技术判断应用程序是否添加了该SDK,从而决定是否要显示360 SDK提供的精品应用
。部分代码如下:
class MyActivity extends Activity { private boolean useQihuSdk; @override public void onCreate(Bundle savedInstanceState) { try { Class.forName("com.qihoo360.union.sdk.UnionManager"); useQihuSdk = true; } catch (ClassNotFoundException ignored) { } }}
最后,运行gradle assembleQihu360
命令即可生成包含360精品应用
模块的渠道包了。
总结
适配是一项dirty工作,尤其是适配的渠道比较多的时候。上面介绍了几种使用Gradle flavor进行适配的例子,基本解决了繁杂的适配工作。
- Android Studio六--Gradle多渠道打包
- Android Studio系列教程六--Gradle多渠道打包
- Android Studio系列教程六--Gradle多渠道打包
- Android Studio系列教程六--Gradle多渠道打包
- Android Studio系列教程六--Gradle多渠道打包
- Android Studio系列教程六--Gradle多渠道打包
- Android Studio系列教程六--Gradle多渠道打包
- Android Studio系列教程六--Gradle多渠道打包
- Android Studio系列教程六--Gradle多渠道打包
- Android Studio系列教程六--Gradle多渠道打包
- Android Studio系列教程六--Gradle多渠道打包
- Android Studio系列教程六--Gradle多渠道打包
- Android Studio系列教程六--Gradle多渠道打包
- Android Studio系列教程六--Gradle多渠道打包
- Android Studio系列教程六--Gradle多渠道打包
- Android Studio系列教程六--Gradle多渠道打包
- Android Studio系列教程六--Gradle多渠道打包
- Android Studio系列教程六--Gradle多渠道打包
- 推荐!国外程序员整理的Java资源大全
- quick2.2与quick3.3的区别(4)
- 体验复杂度—两种排序算法的运行时间
- 大数据的sql优化
- hdoj 5443 The Water Problem 【RMQ】
- Android Studio六--Gradle多渠道打包
- 原地归并算法
- java解析xml的几种方式 DOM解析
- C++Primer第五版 4.9节练习
- Android SharedPreferences的使用
- 很好很强大的vimrc(带注释版)
- windows平台使用cmake编译libnfc 1.7.0 rc6全过程
- MVVM模式--Model,View,ViewModel三者平衡
- 概率与随机函数问题