1.利用productFlavors分渠道打包
背景:当你需要打包的时候,不同的市场需要打出不同的渠道包;如果一个一个打包太麻烦,就用到了productFlavors分渠道打包,
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
flavorDimensions "fuck"
}
buildTypes {
release {
minifyEnabled false
proguardFiles 'proguard-rules.pro'
}
debug{
minifyEnabled false
}
dev {
}
}
productFlavors {
xiaomi {
dimension "fuck"
applicationId "com.lyhinsuning.multi.channelpackagexiaomi"
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]
}
_360 {
dimension "fuck"
applicationId "com.lyhinsuning.multi.channelpackage_360"
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "_360"]
}
baidu {
dimension "fuck"
applicationId "com.lyhinsuning.multi.channelpackagebaidu"
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]
}
wandoujia {
dimension "fuck"
applicationId "com.lyhinsuning.multi.channelpackagewandoujia"
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
}
}
}
flavorDimensions "fuck"
flavorDimensions必须要添加上; "fuck"就是productFlavors中每个渠道的dimension的值,
如果dimension的值不同,谁在前面谁优先级就高
比如:
flavorDimensions "fuck","wotou"
那么这时"fuck"优先级较高一些
//在AndroidManifest.xml文件Application标签中添加,这时就可以在java代码中获取相应的渠道包信息了
<meta-data
android:name="CHANNEL"
android:value="${UMENG_CHANNEL_VALUE}" />
//在java代码中获取相应的渠道包信息
ApplicationInfo appInfo = null;
try {
appInfo = getPackageManager().getApplicationInfo(
getPackageName(), PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException e) {
Log.e("MultiApplication", e.getMessage());
}
if (appInfo != null && appInfo.metaData != null) {
String envService = appInfo.metaData.getString("CHANNEL");
Log.e("MultiApplication", envService);
}
2. lintOptions 配置:用于代码检查
android {
lintOptions {
// true--关闭lint报告的分析进度
quiet true
// true--错误发生后停止gradle构建
abortOnError false
// true--只报告error
ignoreWarnings true
// true--忽略有错误的文件的全/绝对路径(默认是true)
//absolutePaths true
// true--检查所有问题点,包含其他默认关闭项
checkAllWarnings true
// true--所有warning当做error
warningsAsErrors true
// 关闭指定问题检查
disable 'TypographyFractions','TypographyQuotes'
// 打开指定问题检查
enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
// 仅检查指定问题
check 'NewApi', 'InlinedApi'
// true--error输出文件不包含源码行号
noLines true
// true--显示错误的所有发生位置,不截取
showAll true
// 回退lint设置(默认规则)
lintConfig file("default-lint.xml")
// true--生成txt格式报告(默认false)
textReport true
// 重定向输出;可以是文件或'stdout'
textOutput 'stdout'
// true--生成XML格式报告
xmlReport false
// 指定xml报告文档(默认lint-results.xml)
xmlOutput file("lint-report.xml")
// true--生成HTML报告(带问题解释,源码位置,等)
htmlReport true
// html报告可选路径(构建器默认是lint-results.html )
htmlOutput file("lint-report.html")
// true--所有正式版构建执行规则生成崩溃的lint检查,如果有崩溃问题将停止构建
checkReleaseBuilds true
// 在发布版本编译时检查(即使不包含lint目标),指定问题的规则生成崩溃
fatal 'NewApi', 'InlineApi'
// 指定问题的规则生成错误
error 'Wakelock', 'TextViewEdits'
// 指定问题的规则生成警告
warning 'ResourceAsColor'
// 忽略指定问题的规则(同关闭检查)
ignore 'TypographyQuotes'
}
}
3.buildConfigField字段的配置和作用
// 主module的build.gradle中
android{
defaultConfig {
applicationId "com.lyh.msdk"
minSdkVersion 15
targetSdkVersion 28
flavorDimensions "default"
versionCode 1
versionName "1.0"
//app id
buildConfigField "long", "APP_ID", APP_ID
}
}
同目录下build.properties文件
//然后新建一个build.properties文件,里面添加字段,共build.gradle中使用
APP_ID = 1598282460000L
- 禁用动态的BuildConfig可以有效减少增量编译的耗时
如果改一行代码或者资源,执行一次增量build
gradlew app:assemble -PdevBuild --profile
耗时也要较长时间,这就很奇怪了,理论上来说,不该一行代码,应该秒编啊,为了搞清楚这个问题,我们加入--info编译选项,找到更多的信息
gradlew app:assemble -PdevBuild --info | grep -A 3 Executing
加上--info选项时,如果执行了某个task,会解释其原因,为什么会执行,我们可以根据Executing关键字来找到编译慢的原因
发现generateXXXBuildConfig 和XXXjavaWithjavac任务被执行,原因是buildConfig的itemValues发生了变化。目光转向build.gradle
buildConfigField "long", "BUILD_TIMESTAMP", getTimeStamp() + "L"
我们对BuildConfig中的一项输入做了动态变化,getTimeStamp会获取当前的时间,
导致每次build时这个值都会发生变化。
当然在release环境下,这个值确实有用,但是在开发中,就没必要了。
它会导致重新生成BuildConfig.java, 继而导致 javac, dex, package,sign等一系列的任务重新执行,需要对其优化
buildConfigField "long", "BUILD_TIMESTAMP",
project.hasProperty("devBuild")?"000000000":getTimeStamp() + "L"
这样如果是开发环境,每次这个值都是一样的,就会对编译耗时有很大的改进