Android-構建不同環境的Apk

姜家志發表於2017-04-04

在開發Android過程中,常常需要構建不同環境的Apk,比如我們有可能會需要有三個環境

  • 開發環境
  • 測試環境
  • 線上環境

三種環境對應不同的伺服器地址:

   public static final String DEV_URL = "http://dev.domain.com/";
   public static final String TEST_URL = "http://test.domain.com/";
   public static final String RELEASE_URL = "http://www.domain.com/";複製程式碼

可以使用一個變數配置使用不同的環境:

    //0  dev
    //1  test
    //2  release
    public static final int ENV_SETTING = 0;複製程式碼

定義一個獲取不同環境url的方法,預設為dev環境:

    public static String getBaseUrl() {
        switch (ENV_SETTING) {
            case 1:
                return TEST_URL;
            case 2:
                return RELEASE_URL;
            default:
                return DEV_URL;
        }
    }複製程式碼

這樣可以通過設定ENV_SETTING構建不同的Apk:

  • 開發的時候使用預設dev環境
  • 測試的時候給test環境
  • 釋出的時候使用release環境

但是這樣做卻有一些問題,就是每次必須修改ENV_SETTING的值,每次更改都會導致版本庫變動,產生新的提交,如果提交之後的話,其他的開發者不一定會知道版本庫的變動,導致環境不同產生錯誤,還有可能環境不對,生產出了錯誤環境的Apk. 有沒有辦法解決以下問題呢?

  1. 可以構建不同環境的Apk
  2. 不需要修改程式碼
  3. 可以使用不同的簽名
    利用gradle可以解決上面的三個問題,下面就看下如何使用gradle解決上面的問題吧!

buildConfigField

buildConfigField是gradle的一個方法,他的作用是可以給BuildConfig新增變數,賦值等。它的使用:

buildConfigField("int", "ENV_SETTING", "0")

這樣就給BuildConfig中新增加了一個變數EN_SETTING,新增的程式碼如下:

// Fields from build type: debug
  public static final int ENV_SETTING = 0;複製程式碼

在程式碼中使用BuildConfig新增的變數EN_SETTING:

    //0  dev
    //1  test
    //2  release
    public static final int ENV_SETTING = BuildConfig.ENV_SETTING;複製程式碼

buildConfigField通過BuildConfig類可以把gradle裡的配置傳遞給Java程式碼。只是傳遞給了Java值還不能解開始說的三個問題。下面再看下如何在gradle中配置不同的環境。

buildTypes

雖然通過gradle中可以配置ENV_SETTING變數,通過buildConfigField可以讓java程式碼獲取到設定的值。但是在buildTypes中只能設定兩個變數releasedebug:

buildTypes {
        release {
            signingConfig signingConfigs.release
            buildConfigField("int", "ENV_SETTING", "2")
        }
        debug {
            buildConfigField("int", "ENV_SETTING", "0")
        }


    }複製程式碼

buildTypes中只有兩種配置,在build的時候只能生產出兩個Apk:debugrelease,需要第三種環境的Apk,就需要定義一種新的buildTypes,用來構建測試環境的Apk. 新增加一種buildTypes

 buildTypes {
        release {
            signingConfig signingConfigs.release
            buildConfigField("int", "ENV_SETTING", "2")
        }
        debug {
            buildConfigField("int", "ENV_SETTING", "0")
        }
        releaseTest.initWith(buildTypes.release)
        releaseTest {
            buildConfigField("int", "ENV_SETTING", "1")
        }

    }複製程式碼

新增加buildTypes叫做releaseTest(注意不能使用test開頭)。 它繼承了buildTypes.release的配置,可以通過buildConfigFieldENV_SETTING重新賦值,它會覆蓋buildTypes.release的配置。 這樣就有了三種不同的build配置。

assmble*

gradle通過assmble*命令可以打包不同buildTypes的Apk,在右側的gradle工具欄裡面的build選單欄裡面可以看到三種不同的assemble:

  • assembleDebug
  • assembleRelease
  • assembleReleaseTest

這樣就可以根據需要構建不同的Apk,不需要更改程式碼就可以構建不同環境的Apk,而且生成的Apk的名字也能區分出不同的環境,通過上面的配置可以構建出三種Apk:

  • app-debug.apk
  • app-release.apk
  • app-releaseTest.apk

還可以根據上面的配置需要設定不同的Apk簽名,通過signingConfig進行設定。

相關文章