Android Studio 多渠道打包自命名
//—————————————————————————————-
(a)
apply plugin: 'com.android.application'
apply plugin: 'com.droidtitan.lintcleaner'
def releaseTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
def vCode() {
return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))
}
android {
compileSdkVersion 21
buildToolsVersion "22.0.1"
signingConfigs {
apply plugin: 'signing'
release {
storeFile file("../androidkey.keystore")
storePassword "yourpassword"
keyAlias "youralias"
keyPassword "yourkey"
}
}
defaultConfig {
applicationId "your package name"
minSdkVersion 15
targetSdkVersion 21
versionCode Integer.valueOf(vCode())
versionName "2.1.10"
}
//多個版本的打包配置
productFlavors {
Version1{
applicationId "your package name1"
manifestPlaceholders = [GAO_DE_KEY: "your gaode key1", UMENG_KEY: "your umeng key1" ]
}
Version2 {
applicationId "your package name2"
manifestPlaceholders = [GAO_DE_KEY: "your gaode key2", UMENG_KEY: "your umeng key2"]
}
}
buildTypes {
release {
signingConfig signingConfigs.release
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//將release版本的包名重新命名,加上版本及日期
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('release.apk')) {
def fileName = "${variant.productFlavors[0].name}_V${defaultConfig.versionName}_${releaseTime()}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
}
debug {
signingConfig signingConfigs.release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
repositories {
maven { url "https://jitpack.io" }
}
//用來清除無用資源的外掛,詳見https://github.com/marcoRS/lint-cleaner-plugin
lintCleaner {
// Exclude specific files
exclude = ['umeng*.png', '*.xml']
// Ability to ignore all resource files. False by default.
ignoreResFiles = true
}
//將打包後的檔案複製到build目錄下,這樣就不用深入到apk目錄,同時還看不到unaligned的apk了
task copyTask(type: Copy) {
from 'build/outputs/apk/'
into 'build/'
exclude '*-unaligned.apk'
}
task bd(dependsOn: ['assembleDebug', 'assembleRelease', 'copyTask']){
copyTask.mustRunAfter assembleRelease
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
// compile 'com.squareup.retrofit:retrofit:1.9.0'
// compile 'com.squareup.okhttp:okhttp:2.3.0'
// compile 'com.squareup.okhttp:okhttp-urlconnection:2.3.0'
// compile 'com.facebook.stetho:stetho:1.1.1'
// compile 'com.facebook.stetho:stetho-okhttp:1.1.1'
// compile 'io.reactivex:rxandroid:0.24.0'
// compile 'com.jakewharton:butterknife:6.1.0'
compile 'com.facebook.fresco:fresco:0.5.2+'
compile 'me.imid.swipebacklayout.lib:library:1.0.0'
compile 'se.emilsjolander:stickylistheaders:2.6.0'
compile 'de.greenrobot:eventbus:2.4.0'
compile 'com.github.PhilJay:MPAndroidChart:v2.0.9'
compile 'com.google.code.gson:gson:2.3.1'
compile 'com.android.support:support-v13:22.2.0'
compile project(':carShopSyncLib')
}
//—————————————————————————————-
(b)
專案切換到Android Studio有一段時間了,來聊聊多渠道打包的做法。
1.在productFlavors新增你需要的所有渠道
android {
productFlavors { //在這裡新增你所有需要打包的渠道
dev {}
google {}
myapp {}
xiaomi {}
app360 {}
wandoujia {}
}
//新增如下程式碼
productFlavors.all { flavors->
flavors.manifestPlaceholders=[CHANNEL_VALUE:name]
}
}
同時修改androidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="cn.op.zdf"
android:versionCode="25"
android:versionName="3.1.2">
<application
android:name=".myApplication">
<-- 在manifest中新增如下程式碼--->
<meta-data
android:name="UMENG_CHANNEL"
android:value="${CHANNEL_VALUE}"/>
</application>
</manifest>
OK,在命令列執行gradle build,大功告成。你可以去喝杯茶了。
2.如何給apk重新命名
恩,釋出產品的時候我們需要如下的命名規則
release版本的命名規則如下:
產品名稱-版本號-渠道號-sign-42.apk
在build.gradle中新增如下程式碼
//獲取時間戳
def getDate() {
def date = new Date()
def formattedDate = date.format('yyyyMMddHHmm')
return formattedDate
}
//從androidManifest.xml中獲取版本號
def getVersionNameFromManifest(){
def manifestParser = new com.android.builder.core.DefaultManifestParser()
return manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile)
}
android{
//修改生成的apk名字
applicationVariants.all{ variant->
variant.outputs.each { output->
def oldFile = output.outputFile
def newName = '';
if(variant.buildType.name.equals('release')){
// println(variant.productFlavors[0].name)
def releaseApkName = 'yjf-android-v' + getVersionNameFromManifest() + '-' + variant.productFlavors[0].name + '-sign-42.apk'
output.outputFile = new File(oldFile.parent, releaseApkName)
}
if(variant.buildType.name.equals('beta')){
newName = oldFile.name.replace(".apk", "-v" + getVersionNameFromManifest() + "-build" + getDate() + ".apk")
output.outputFile = new File(oldFile.parent, newName)
}
if(variant.buildType.name.equals('debug')){
}
}
}
}
哦,怎麼取得版本號?怎麼取得渠道號?怎麼判斷是不是release版本?上面的程式碼裡面都有。
我的專案是從eclipse中遷移過來的,所以我是從manifest檔案中讀取的版本號,就是上面的那個函式 getVersionNameFromManifest()
如果你的版本號定義在build.gradle中,那defaultConfig.versionName就是你的版本號。
//———————————————————————————-
下面是我自己的命名:
apply plugin: 'com.android.application'
//apply plugin: 'com.android.databinding'
def appName() {
return "APP_NAME"
}
def releaseTime() {
return new Date().format("yyyyMMddHHmm", TimeZone.getDefault())
}
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "xxxx.xxxx.xxxx.xxxxx"
minSdkVersion 15
targetSdkVersion 19
versionCode 9
versionName "1.0.14"
// Enabling multidex support.
// dex突破65535的限制
multiDexEnabled true
}
signingConfigs {
debug {
storeFile file('tools/signature.keystore')
storePassword SIGNING_STOREPASSWORD
keyAlias SIGNING_KEYALIAS
keyPassword SIGNING_KEYPASSWORD
}
release {
storeFile file('tools/signature.keystore')
storePassword SIGNING_STOREPASSWORD
keyAlias SIGNING_KEYALIAS
keyPassword SIGNING_KEYPASSWORD
}
}
buildTypes {
debug {
// 不顯示Log
buildConfigField "boolean", "LOG_DEBUG", "false"
//混淆
minifyEnabled true
//Zipalign優化
zipAlignEnabled true
// 移除無用的resource檔案
shrinkResources true
//載入預設混淆配置檔案 progudard-android.txt在sdk目錄裡面,不用管,proguard.cfg是我們自己配的混淆檔案
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//簽名
signingConfig signingConfigs.debug
//將release版本的包名重新命名,加上版本及日期,連線真機除錯的時候請註釋掉
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('debug.apk')) {
//def fileName = "${variant.productFlavors[0].name}_V${defaultConfig.versionName}_${releaseTime()}.apk"
def productFlavorsName = variant.productFlavors[0].name;
def fileName = "${appName()}.V${defaultConfig.versionName}.${releaseTime()}.alpha."+productFlavorsName+".apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
}
release {
// 不顯示Log
buildConfigField "boolean", "LOG_DEBUG", "false"
//混淆
minifyEnabled true
//Zipalign優化
zipAlignEnabled true
// 移除無用的resource檔案
shrinkResources true
//載入預設混淆配置檔案 progudard-android.txt在sdk目錄裡面,不用管,proguard.cfg是我們自己配的混淆檔案
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//簽名
signingConfig signingConfigs.release
//
//將release版本的包名重新命名,加上版本及日期
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('release.apk')) {
//def fileName = "${variant.productFlavors[0].name}_V${defaultConfig.versionName}_${releaseTime()}.apk"
def productFlavorsName = variant.productFlavors[0].name;
def fileName = "${appName()}.V${defaultConfig.versionName}.${releaseTime()}.release."+productFlavorsName+".apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
}
}
sourceSets {
main {
//manifest.srcFile 'AndroidManifest.xml'
//java.srcDirs = ['src']
//resources.srcDirs = ['resources']
//res.srcDirs = ['res']
//assets.srcDirs = ['assets']
//aidl.srcDirs = ['src']
//renderscript.srcDirs = ['src']
jniLibs.srcDirs = ['libs']
}
androidTest.setRoot('tests')
}
allprojects {
repositories {
jcenter()
mavenCentral();
}
}
lintOptions {
abortOnError false
//disable 'InvalidPackage'
}
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/DEPENDENCIES'
}
// 在生成的apk檔案,修改下命名而已
// applicationVariants.all { variant ->
// variant.outputs.each { output ->
// def outputFile = output.outputFile
// if (outputFile != null && outputFile.name.endsWith('.apk')) {
// //def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}.apk")
// def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}.apk")
// output.outputFile = new File(outputFile.parent, fileName)
// }
// }
// }
productFlavors {
yijiajiao {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "XXXX"]
}
yingyongbao {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "XXXX"]
}
xiaomi {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "XXXX"]
}
wandoujia {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "XXXX"]
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:22.2.1'
compile '......'
}
生成的apk名字是:
APP_NAME.V1.0.14.201510300950.alpha.yijiajiao.apk
APP_NAME.V1.0.14.201510300950.alpha.yingyongbao.apk
APP_NAME.V1.0.14.201510300950.alpha.xiaomi.apk
APP_NAME.V1.0.14.201510300950.alpha.wandoujia.apk