最近项目中每次遇到适配不同渠道的问题就头大,今天就在此总结整理一下遇到的问题吧。
首先假定一种需求:一款APP有两种版本,分别是免费版和付费版,需要在三个国家(中国,美国,英国)上线,那么一共就是6个版本,其中英国免费版需要添加一个google广告依赖。
分渠道当然是使用 productFlavors了。
productFlavors {
cnpayed {
applicationId= "com.demo.pay"
minSdkVersion 21
}
cnfree {
applicationIdSuffix= "<span style="font-family: Arial, Helvetica, sans-serif;">com.demo.cn</span><span style="font-family: Arial, Helvetica, sans-serif;">.free"</span>
minSdkVersion 21
}
<span style="white-space:pre"> </span>...
<span style="white-space:pre"> </span>...
}
纳尼??真的这么写么,用长者的话说:too young too simple!!先贴下代码
flavorDimensions "payment", "country"
productFlavors {
payed {
dimension "payment"
applicationIdSuffix= ".pay"
minSdkVersion 21
}
free {
applicationIdSuffix= ".free"
dimension "payment"
minSdkVersion 21
}
cn {
dimension "country"
applicationIdSuffix =".cn"
minSdkVersion 11
}
us {
dimension "country"
applicationIdSuffix =".us"
minSdkVersion 11
}
uk {
dimension "country"
applicationIdSuffix =".uk"
minSdkVersion 11
}
}
解释一下,首先分两个维度:付费情况和国家,然后分别列出两个维度的内容并且标出属于哪个维度。
付费情况
payed {
dimension "payment"
applicationIdSuffix= ".pay"
minSdkVersion 21
}
free {
applicationIdSuffix= ".free"
dimension "payment"
minSdkVersion 21
}
国家
cn {
dimension "country"
applicationIdSuffix =".cn"
minSdkVersion 11
}
us {
dimension "country"
applicationIdSuffix =".us"
minSdkVersion 11
}
uk {
dimension "country"
applicationIdSuffix =".uk"
minSdkVersion 11
}
来,看一下build variant 情况

不同的渠道都有了,吊吊的有木有?
再说一下 applicationIdSuffix
见名知意,就是包名后缀了,会在默认的包名后面添加,这样每个渠道都有自己的包名了。
接下来,我们说一下为不同渠道添加依赖的问题
假设我们为中国免费版本添加rxJava
freeCnCompile 'io.reactivex:rxandroid:1.1.0' 就是我们通常看到的flavorCompile 渠道名加上compile了。
再这里提出一个问题,假如我们有20个渠道,其中17个渠道需要分别处理的10个依赖包,怎么搞??憋笑,这个是真实需求啊!!!
来看看我之前是怎么处理的
flavor1Compile 依赖包1
flavor1Compile 依赖包2
flavor1Compile 依赖包3
。
。
。
flavor2Compile 依赖包1
flavor2Compile 依赖包2
flavor2Compile 依赖包3
.。。
。
尼玛啊,想当年老师说过:看到重复代码,就像看到脸上有一口痰一样恶心有木有,有木有!!!
先放一放,我们解决下一个问题:
项目中需要分渠道使用plugin怎么搞?,flavorApply plugin 真心没有啊,捋一捋思路。嗯,先获取当前渠道名,然后使用task应用不同的插件
贴一下代码
import java.util.regex.Matcher
import java.util.regex.Pattern
def String getCurrentFlavor() {
Gradle gradle = getGradle()
String tskReqStr = gradle.getStartParameter().getTaskRequests().toString()
Pattern pattern;
if (tskReqStr.contains("assemble"))
pattern = Pattern.compile("assemble(\\w+)(Release|Debug)")
else
pattern = Pattern.compile("generate(\\w+)(Release|Debug)")
Matcher matcher = pattern.matcher(tskReqStr)
if (matcher.find())
return matcher.group(1).toLowerCase()
else {
println "NO MATCH FOUND"
return "";
}
}
gradle.projectsEvaluated {
preBuild.dependsOn(applyGoogleServiceByProperty)
}
// Then check on the parameter, which comes from the command line
task applyGoogleServiceByProperty {
println getCurrentFlavor();
def flavorType = ""
flavorType = getCurrentFlavor();
if (flavorType.equals("payedCn")) {
apply plugin: 'com.google.gms.google-services'
}
}
虾面,我们解决一下刚才提出的问题
<pre name="code" class="html">dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
def currentFlavor = getCurrentFlavor()
if (currentFlavor.equals("payedCn")||currentFlavor.equals("payedUs")) {
compile 'com.github.bumptech.glide:glide:3.7.0'
} else {
compile 'com.google.firebase:firebase-analytics:9.2.1'
}
compile 'com.android.support:appcompat-v7:24.0.0'
compile 'com.android.support:support-v4:24.0.0'
}
贴一下参考资料
http://jiajixin.cn/2015/08/07/gradle-android/
https://chaosleong.gitbooks.io/gradle-for-android/content/advanced_build_customization/shrinking_resources.html
http://tech.meituan.com/mt-apk-adaptation.html