天天看點

android不同環境生成的apk不同名,防止環境管道選擇錯誤

1.原因

我是一個粗心的人,常常要上線了然後即将發上上線環境的時候,發現app采用的是app測試位址(内網),吓得一頭汗。

為了避免這個問題,打算使用gradle工具設定我的apk名。當apk名有測試二字的時候,自然是測試環境,看一眼就知道錯了,避免上線版本發錯。

步驟如下:

1.根據不同環境,選擇不同網址,此處采用enum形式:

public class UrlConfig {
    public static String getMainUrl(){
        MainUrlEnum mainUrlEnum = MainUrlEnum.getMainUrlByType(getDevelopType());
        return mainUrlEnum.getUrl();
    }

    private static int kDevelopType;
    public static int getDevelopType() {
        if (kDevelopType == 0) {
            try {
                 ApplicationInfo appInfo = SuperApp.getApp().getPackageManager().getApplicationInfo(SuperApp.getApp().getPackageName(), PackageManager.GET_META_DATA);
                this.kDevelopType = appInfo.metaData.getInt("urlType");
            } catch (PackageManager.NameNotFoundException e) {
                // TODO Auto-generated catch block
                ToastUtil.shorts("錯誤,請設定urlType!");
            }
        }
        return      
public SuperApp extends Application{
    private static SuperApp app;
    @Overriade
    public void onCreate() {
        app = this;
    }

    public static void getSuperApp(){
        return      
public enum MainUrlEnum {
    TEST(1, "測試環境網址");//此處填入測試網址
    REAL(2, "正式環境網址");//此處填入正式網址
    //可繼續追加
    private int urlType;
    private String url;

    MainUrlEnum(int urlType, String url) {
        this.urlType = urlType;
        this.url = url;
    }

    public String getUrl() {
        return url;
    }

    public int getUrlType() {
        return urlType;
    }

    public static MainUrlEnum getMainUrlByType(int urlType) {
        if (urlType == TEST.urlType)
            return TEST;
        else if (urlType == REAL.urlType)
            return REAL;
        return      

2.在manifest進行設定,因為gradle也要設定,用${xx}形式代替

data
            android:name="urlType"
            android:value="${urlType}"      

3.建立一個config.gradle用于設定urlType版本号資訊:

ext {
    android = [
            versionCode:        1,
            versionName:        "1.0",
            urlType:            1      

4.在工程的build.gradle中配置config.gradle,開頭加入以下代碼:

apply from: "config.gradle"      

5.在運作的module裡面配置manifest的holder和版本:

android{
compileSdkVersion SDK版本如22
    buildToolsVersion SDK版本如22.0.1
defaultConfig {
        applicationId 你的包名如com.xx.xx
        minSdkVersion 最低版本如9
        targetSdkVersion 目标版本如22
        versionCode rootProject.ext.android.versionCode
        versionName rootProject.ext.android.versionName
        multiDexEnabled true
    }
buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            manifestPlaceholders = [
                "urlType":rootProject.ext.android.urlType
            ]
        }
        debug{
            minifyEnabled false
            manifestPlaceholders = [
                    "urlType":rootProject.ext.android.urlType
            ]
        }
    }
}      

6.在運作的module裡面配置apk資訊:

android{
android.applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile
            def fileName
            if (outputFile != null && outputFile.name.endsWith('.apk')) {
                if (variant.buildType.name.equals('release')) {
                    if(rootProject.ext.android.urlType == 1){
                        fileName = "測試項目名稱${defaultConfig.versionName}.apk"
                    }elseif(rootProject.ext.android.urlType == 2){
                        fileName = "項目名稱${defaultConfig.versionName}.apk"
                    }//可繼續追加
                } else if (variant.buildType.name.equals('debug')) {
                    fileName = "${defaultConfig.versionName}.apk"
                }
                output.outputFile = new File(outputFile.parent, fileName)
            }
        }
    }
}      

這樣,簽名後(variant.buildType.name.equals(‘release’)),如果測試環境生成apk就叫做”測試項目名稱1.0.apk”,正式環境叫做”項目名稱1.0.apk”,一眼就看出請求位址環境了;沒簽名的不顯示項目名稱【不簽名肯定不會釋出的,而且沒有項目名稱已經很明顯了】成為“1.0.apk”。而且以後别人接手也可以馬上根據gradle判斷出urlType含義,當環境或者管道越多的時候,這個方式的優勢越明顯。

gradle 3.0不相容問題

改動後格式如下:

android{
android.applicationVariants.all { variant ->
        variant.outputs.all { output ->
            def outputFile = outputFileName
            def fileName
            if (outputFile != null && outputFile.endsWith('.apk')) {
                if (variant.buildType.name.equals('release')) {
                    if(rootProject.ext.android.urlType == 1){
                        fileName = "測試項目名稱${defaultConfig.versionName}.apk"
                        outputFileName=fileName
                    }elseif(rootProject.ext.android.urlType == 2){
                        fileName = "項目名稱${defaultConfig.versionName}.apk"
                        outputFileName=fileName
                    }//可繼續追加
                } else if (variant.buildType.name.equals('debug')) {
                    fileName = "項目名稱.apk"//注意此處做好固定,否則aapt打包的時候容易報錯
                    outputFileName=fileName
                }
            }

        }
    }
}