概述
在公司开发时,一般会模拟出几套环境,ps,测试环境、准生产环境、发布环境等,同时 Android 市场繁多,为了方便后期数据分析,在发布的时候还要添加一个渠道统计,一般会用到友盟统计,这就给我们的打包带来了麻烦。
gradle
好在android studio的gradle脚本十分强大,给我们的构建带来了方便。
首先,我们定义一个配置文件,方便后面管理
gradle.properties
,因为我的项目是区分中英文的,所以定义了两个packageName
,打包的时候也算是两个产品
gradle.properties:
// build_tools版本号
ANDROID_BUILD_TOOLS_VERSION=22.0.1
// build_dk版本号
ANDROID_BUILD_SDK_VERSION=22
// version_name
VERSION_NAME=2.1
// version_code
VERSION_CODE=2100
// 包名
// PACKAGE= xxxx
// english version
PACKAGE= xxxx.en
//minSdkVersion
ANDROID_BUILD_MIN_SDK_VERSION=15
//targetSdkVersion
ANDROID_BUILD_TARGET_SDK_VERSION=22
// grade_version
GRADLE = com.android.tools.build:gradle:1.5.0
build.gradle(app 工程目录下):
//声明是Android程序,和library区别
apply plugin: 'com.android.application'
// 因为项目中使用了retrolambda
apply plugin: 'me.tatarka.retrolambda'
// 打包时间
def releaseTime() {
return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))
}
android {
//编译SDK的版本
compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
// build tools的版本
buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION
defaultConfig {
//应用的包名,定义在gradle.properties
applicationId project.PACKAGE
minSdkVersion Integer.parseInt(ANDROID_BUILD_MIN_SDK_VERSION)
targetSdkVersion Integer.parseInt(ANDROID_BUILD_TARGET_SDK_VERSION)
versionCode Integer.parseInt(project.VERSION_CODE)
versionName project.VERSION_NAME
// dex突破65535的限制,为大程序而设
multiDexEnabled true
// AndroidManifest.xml 里面CHANNEL的value为 ${CHANNEL_VALUE}
manifestPlaceholders = [CHANNEL_VALUE: "name"]
}
//执行lint检查,有任何的错误或者警告提示,都会终止构建,我们可以将其关掉。
lintOptions {
checkReleaseBuilds false
abortOnError false
// 防止在发布的时候出现因MissingTranslation导致Build Failed!
disable 'MissingTranslation'
}
dexOptions {
incremental true
javaMaxHeapSize "8g"
jumboMode = true
preDexLibraries = false
threadCount ="8"
}
//签名
signingConfigs {
debug {
}
relealse {
storeFile file('xxx.keystore')
storePassword '***'
keyAlias 'xxx'
keyPassword '***'
}
}
// 打包
buildTypes {
//debug 版本
// debug {
// buildConfigField "int", "ENV", "0"
// minifyEnabled true
// zipAlignEnabled true
// shrinkResources true
// proguardFile 'proguard-rules.pro'
// signingConfig signingConfigs.relealse
// }
// pre {
// buildConfigField "int", "ENV", "1"
// minifyEnabled false
// zipAlignEnabled false
// shrinkResources false
// signingConfig signingConfigs.relealse
// }
// online {
// buildConfigField "int", "ENV", "2"
// minifyEnabled false
// zipAlignEnabled false
// shrinkResources false
// signingConfig signingConfigs.relealse
// }
release {
// 定义ENV变量,可以通过BuildConfig.ENV 来获取,进行一些接口环境变化的操作
buildConfigField "int", "ENV", "2"
//混淆
minifyEnabled true
//Zipalign优化
zipAlignEnabled true
// 移除无用的resource文件
shrinkResources true
//混淆配置文件
proguardFile 'proguard-rules.pro'
//签名
signingConfig signingConfigs.relealse
}
}
//渠道Flavors
productFlavors {
Market_Google_Play {}
// Market_xiaomi {}
// Market_wandoujia {}
// Market_Default {}
// Market_Amazon {}
// Market_yingyongbao {}
// Market_360 {}
// Market_baidu {}
}
// Java版本
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// 替换manifest中定义的占位符
productFlavors.all { flavor ->
flavor.manifestPlaceholders = [CHANNEL_VALUE: name]
}
// apk输出重命名
applicationVariants.all { variant ->
variant.outputs.each { output ->
// oldName
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')){
// 获取中英文版本
def isEn = variant.applicationId.endsWith('.en')
def newName = ''
def version= "-v${defaultConfig.versionName}"
def time = "-${releaseTime()}.apk"
def enName = 'appEN'
def cnName = 'appCN'
// release版本
// if(variant.buildType.name.equals('release')) {
//
// // 获取渠道号
// def productFlavor = variant.productFlavors[0].name
//
// if (isEn) {
// newName = enName + version + '-' + productFlavor + time
//
// } else {
// newName = cnName + version + '-' + productFlavor + time
// }
// }else if (variant.buildType.name.equals('pre')){
// if (isEn) {
// newName = enName + version + '-pre-online' + time
//
// } else {
// newName = cnName + version + '-pre-online' + time
// }
// }else if (variant.buildType.name.equals('online')){
// if (isEn) {
// newName = enName + version + '-online' + time
//
// } else {
// newName = cnName + version + '-online' + time
// }
// }else{
if (isEn) {
newName = enName + version + '-debug' + time
} else {
newName = cnName + version + '-debug' + time
}
// }
output.outputFile = new File(outputFile.parent, newName)
}
}
}
}
retrolambda {
javaVersion JavaVersion.VERSION_1_7
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:22.2.1'
compile 'com.android.support:design:22.2.1'
compile 'com.android.support:recyclerview-v7:22.2.1'
compile 'com.annimon:stream:1.0.1'
compile project(':mylibrary')
}
最后会在app/build/outputs/apk下生成相应的文件
debug:name-version-debug-time.apk
release: name-version-productFlavors-time.apk
AndroidManifest.xml
<application>
<meta-data
android:name="UMENG_APPKEY"
android:value="54d32a3afd98c511cf000629" />
<meta-data
android:name="UMENG_CHANNEL"
android:value="${CHANNEL_VALUE}" />
</application>