android studio多渠道多环境打包自动重命名
16lz
2021-01-23
概述
在android开发中,公司经常会模拟出几套环境,ps,测试环境、准生产环境、发布环境等,同时 Android 市场繁多,为了方便后期数据分析,在发布的时候还要添加一个渠道统计,一般会用到友盟统计,这就给我们的打包带来了麻烦。
gradle
好在android studio的gradle脚本十分强大,给我们的构建带来了方便。
首先,我们定义一个配置文件,方便后面管理
gradle.properties
,因为我的项目是区分中英文的,所以定义了两个packageName,打包的时候是两个产品
// build_tools版本号ANDROID_BUILD_TOOLS_VERSION=22.0.1// build_dk版本号ANDROID_BUILD_SDK_VERSION=22// version_nameVERSION_NAME=2.1// version_codeVERSION_CODE=2100// 包名// PACKAGE= xxxx// english versionPACKAGE= xxxx.en//minSdkVersionANDROID_BUILD_MIN_SDK_VERSION=15//targetSdkVersionANDROID_BUILD_TARGET_SDK_VERSION=22// grade_versionGRADLE = com.android.tools.build:gradle:1.5.0
build.gradle(app 工程目录下)
//声明是Android程序,和library区别apply plugin: 'com.android.application'// 因为项目中使用了retrolambdaapply 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下生成相应的文件
AndroidManifest.xml
<application><meta-data android:name="UMENG_APPKEY" android:value="54d32a3afd98c511cf000629" /> <meta-data android:name="UMENG_CHANNEL" android:value="${CHANNEL_VALUE}" /> </application>
更多相关文章
- Android如何自定义一个view——绘制篇
- android 深入研究ratingbar自定义
- Android(1.1-4.2) platform 开发包【全版本】
- ubuntu 12.04 下安装android编译环境
- Android - 自定义Dialog内部透明,外部有遮罩
- 火爆新东西,仿QQ版本的ResideMenuItem框架(最新QQ版本的)
- android C/C++ source files 全局宏定义 .
- IDEA和Android Studio设置自定义背景图片
- Android自定义底部显示对话框