Android Studio 多渠道打包自命名

可參照:
(1)http://blog.chinaunix.net/uid-20771867-id-5106723.html
(2)http://www.th7.cn/Program/Android/201501/380594.shtml

//—————————————————————————————-
(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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章