接上篇,这篇继续讲的是Android中Gradle的使用。做Android的同学都知道,国内应用市场混杂,没有谷歌爸爸统一的支持,这可苦了我们做开发的,每次上线打包都是N多个市场,费时费力。
还好Gradle的强大,可以帮助我们一键打包出各种渠道的包。
增加多渠道
1、首先在Manifest中增加 meta-data
在application 下增加渠道名称预留
<meta-data
android:name="KISTLER_CHANNEL"
android:value="${KISTLER_CHANNEL_VALUE}">
</meta-data>复制代码
名字可以自己取,只需下面对应填写。
2、在Gradle中添加 Flavors
我自己添加了这几个渠道,数字开头的得加上下划线
productFlavors {
小米 {}
豌豆荚 {}
华为 {}
应用宝 {}
百度 {}
_360 {}
}
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [KISTLER_CHANNEL_VALUE: name]
}
复制代码
如果你的Gradle版本在3.0以上,还需要在上面添加上 flavorDimensions
举个?
flavorDimensions "default"
productFlavors {
小米 {}
豌豆荚 {}
华为 {}
应用宝 {}
百度 {}
_360 {}
}
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [KISTLER_CHANNEL_VALUE: name]
}复制代码
这时候你打包就会发现你的 buildTypes 和 Flavors 的组合。
如果你打包,你会发现你输出的apk包在你的目标如今下。生成了Flavors中的文件夹名称,每个apk包一个文件夹,而且包名相对混乱,比如下面这样
这样非常不利于我们上传及保留历史包,有没有什么方法可以修改包名称,并且让他存在于同一个文件夹下呢,当然是可以的。
3、修改包生成路径及包命名规则
这里分为Gradle3.0之前和之后两种方法。
1、3.0之前
在release 下添加下面代码
applicationVariants.all { variant ->
variant.outputs.each { output ->
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def apkFile = new File(
output.outputFile.getParent(), "中国奇石网_${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk")
output.outputFile = apkFile
}
}
}复制代码
2、3.0之后
3.0之后不允许修改 output.outputFile 会提示报错。
applicationVariants.all { variant ->
variant.outputs.all { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def fileName = "中国奇石网_${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"
outputFileName = fileName
}
}
}复制代码
这样就可以修改apk的名称,但是还是会像刚才一样每个apk文件处于不同的文件夹中,在最后加上额外指定地址
applicationVariants.all { variant ->
variant.outputs.all { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def fileName = "中国奇石网_${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"
outputFileName = fileName
variant.packageApplication.outputDirectory = new File("/Users/joker/Android/AppOutPut/中国奇石网" + defaultConfig.versionName)
}
}
}复制代码
这样加入variant.packageApplication.outputDirectory就可以指定生成的目录。
这样就会遇到一个问题,我直接运行时候,安装不上,看下错误日志是包不存在。怎么回事呢。原来是我们更换了生成如今,安装命令找不到apk文件。可是为什么我放在release中,debug运行还是会执行呢,这个我暂时不知道,知道的朋友可以评论告诉我。我的解决办法是加个判断。确保只在release时候执行。
applicationVariants.all { variant ->
if (variant.buildType.name == 'release')
variant.outputs.all { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def fileName = "中国奇石网_${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"
outputFileName = fileName
variant.packageApplication.outputDirectory = new File("/Users/joker/Android/AppOutPut/中国奇石网" + defaultConfig.versionName)
}
}
}复制代码
选择打包时候,你可能会发现,你的 buildTypes 中和 Flavors 进行全组合了,这样会导致很杂乱,我们只需要release和Flavors进行组合。
4、忽略某些buildTypes与Flavors结合
variantFilter { variant ->
if (variant.buildType.name != 'release') {
variant.setIgnore(variant.getFlavors().get(0).name != '_360')
}
}复制代码
这段代码加在Android层级下,我的需求是只在release时候和Flavors结合,其他情况忽略结合。为什么不能直接设置setIgnore直接为true呢,应为这样会导致buildTypes失效,除release的无结合内容。
这下整个世界都干净了
大功告成,这样在打包release时候就可以一键生成所有渠道的包?
原文地址:http://jokehanj.com/index.php/2018/03/21/gradle_qing_song_duo_qu_dao_da_bao/