使用 Gradle 對應用進行個性化定製

啥也不說了,直接進入主題吧。本篇文章主要根據實際開發中遇到的需求,講解使用 Gradle 對應用的不一樣版本進行個性化定製。html

場景介紹

  1. 通常的應用基本上都有正式服和測試服,這個就不須要多說了。可是有些應用可能還有超管服務器專供運營人員使用,對應用內的一些內容進行監管,具備一些管理員纔有的操做權限。
  2. 開發過程當中發佈測試服務器的安裝包須要在版本號後面增長版本序號,超管服務器的包在版本號後面增長管理員文字,線上包則正常顯示版本號。
  3. 每次打包 versionCode 自增,避免發版時忘記手動修改致使老版本不能覆蓋安裝。
  4. 超管包的渠道名爲 admin,平常運行的 debug 包渠道名爲 test,上線的包使用加固軟件進行多渠道加固。
  5. debug 包和 release 包使用一樣的簽名,避免直接運行的 debug 包由於簽名問題不能使用須要校驗簽名的第三方服務,好比:QQ 登陸,微信登陸,高德地圖。
  6. debug 包打印日誌信息,release 包不打印日誌信息

以上某些場景從我工做以來就一直存在,之前用 eclipse 開發時除了每次都手動去修改一些開關變量也沒啥好辦法,多是由於當時菜 ╮(╯▽╰)╭(若是大家有什麼好方法的話)。android

後來切換到 Android Studio 後使用 Gradle 進行依賴管理已經讓人非常欣喜,既然如此能不能使用 Gradle 將以上問題通通解決,徹底自動化呢?答案是:必須的。git

解決問題

先上完整的 Gradle 配置。服務器

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
        applicationId "com.imliujun.gradle"
        minSdkVersion 16
        targetSdkVersion 25
        versionCode gitVersionCode()  //獲取 git 的 commit 次數
        versionName rootProject.ext.versionName

        manifestPlaceholders = [UMENG_APP_KEY      : "填你的友盟 APP KEY",
                                UMENG_CHANNEL_VALUE: "默認的渠道名"]
    }

    signingConfigs {
    //在這裏配置相關的簽名信息
        keyStore {
            storeFile file("test.jks")
            storePassword "111111"
            keyAlias "test"
            keyPassword "111111"
        }
    }

    buildTypes {
        release {
            // 不顯示Log
            buildConfigField "boolean", "LOG_DEBUG", "false"
            signingConfig signingConfigs.keyStore //設置簽名文件
        }

        debug {
            // 顯示Log
            buildConfigField "boolean", "LOG_DEBUG", "true"
            versionNameSuffix "-debug"  //設置後綴
            signingConfig signingConfigs.keyStore  //設置簽名文件
            manifestPlaceholders.UMENG_CHANNEL_VALUE = "test" //修改渠道名
        }
    }

    productFlavors {
        offline {
            buildConfigField "String", "DOMAIN_NAME", "\"https://offline.domain.com/\""
            versionName getTestVersionName() //修改 versionName
        }

        online {
            buildConfigField "String", "DOMAIN_NAME", "\"https://online.domain.com/\""
        }

        admin {
            buildConfigField "String", "DOMAIN_NAME", "\"https://admin.domain.com/\""
            versionName rootProject.ext.versionName + "-管理員" //修改 versionName
            manifestPlaceholders.UMENG_CHANNEL_VALUE = "admin" //修改渠道名
        }
    }
}複製代碼

根目錄下的 build.gradle 文件進行以下配置,主要是將版本號和測試包的序號抽取出來:微信

ext {
    versionName = "2.0.2"
    testNum = "0001"
}

def getTestVersionName() {
    return String.format("%s.%s", rootProject.ext.versionName,
            rootProject.ext.testNum)
}

static int gitVersionCode() {
    def count = "git rev-list HEAD --count".execute().text.trim()
    return count.isInteger() ? count.toInteger() : 0
}複製代碼

下面就根據場景來依次介紹對應的配置代碼。app

1. 配置服務器版本

這裏建立了三個 flavor,分別是 offline 測試服online 正式服admin 超管服。而且經過 buildConfigField 動態配置服務器的 URL 常量值到編譯後自動生成的 BuildConfig 類中。dom

自動生成的 BuildConfig 類
自動生成的 BuildConfig 類

圖中能夠看到,不止有 DOMAIN_NAME 常量值,還有一個 FLAVOR 常量。這個 FLAVOR 常量中的值是 offline,表明當前在 offline 這個版本上面。那怎麼切換到其餘的服務器呢?eclipse

切換不一樣的變種版本
切換不一樣的變種版本

點開左下角的 Build Variants, 能夠自由切換當前運行的版本。須要在管理員包中開啓一些高級的功能,能夠判斷 FLAVOR 的值是否是 admin,若是是的話就顯示管理員的操做佈局。固然必不可少的要對用戶權限進行校驗哦。工具

2. 定製 versionName

你們看上圖 BuildConfig 類中 VERSION_NAME 常量的值爲 2.0.2.0001-debug,當前是測試服的 debug 包,因此 versionName 應該是正常的 2.0.2 版本後面拼上當前出包的序號 0001 ,再拼上 debug 的後綴,因此完整的版本號是 2.0.2.0001-debug佈局

看看不一樣服務器版本的 VERSION_NAME

  • offlineRelease 版本爲 2.0.2.0001
  • offlineDebug 版本爲 2.0.2.0001-debug
  • adminRelease 版本爲 2.0.2-管理員
  • adminDebug 版本爲 2.0.2-管理員-debug
  • onlineRelease 版本爲 2.0.2
  • onlineDebug 版本爲 2.0.2-debug

若是咱們接口須要上傳版本號給服務器呢?確定不能直接上傳這些定製化後的 VERSION_NAME,那麼咱們在 Gradle 中增長一個 buildConfigField 將原始的版本號存起來就行了。

buildConfigField "String", "versionNumber", "\"${rootProject.ext.versionName}\""複製代碼

3. versionCode 自增

這裏採用了主流的方式,使用 gitcommit 次數做爲 versionCode 的值。不用擔憂這個值會超過 int 的上限,你得敲爛多少鍵盤才能提交 2147483648次 commit

static int gitVersionCode() {
    def count = "git rev-list HEAD --count".execute().text.trim()
    return count.isInteger() ? count.toInteger() : 0
 }複製代碼

4. 個性化渠道名

Gradle 多渠道打包的文章太多了,相關的基礎我就不講了。簡單講下本文相關的配置吧。

經過定義 manifestPlaceholders 鍵值對,在 AndroidManifest.xml 文件中使用佔位符的方式動態輸入 UMENG_APPKEYUMENG_CHANNEL

而後在 debugbuildType 中修改渠道名爲 test,在 adminFlavor 中修改渠道名爲 admin。若是選擇 adminDebug 版本,則渠道名爲 testbuildType 中的配置會覆蓋掉 Flavor 中的配置。

因爲咱們線上使用第三方加固,因此多渠道包就交給第三方加固軟件來生成了。

關於多渠道打包我還有兩句話要說,之前使用 Gradle 進行多渠道打包,經過代碼自定義修改 apk 文件的輸出路徑,Android Studio 編譯的時候時不時的報一些文件找不到的錯誤,之前都是經過在 Gradle 文件中隨便修改一點東西而後刷新一下 Gradle 文件來解決。如今我打包不修改輸出路徑,再也沒遇到之前的那些問題了。

建議你們使用 assemble 命令來進行打包,好比我要出一個測試包使用 ./gradlew assembleOfflineRelease 命令,apk 文件生成在 /build/outputs/apk/ 目錄下。直接執行 assemble 命令是編譯 Build Variants 中的全部包,若是你要編譯指定版本的包,直接在 assemble 命令後面拼上指定的 Build Variant 就行了。

5. debug 包使用 release 簽名

這個問題在 eclipse 時代,能夠直接在設置裏面配置 debug 簽名文件爲 release 的簽名文件。
Android Studio 只須要在 Gradle 中配置就行了。

首先配置簽名文件的信息:

signingConfigs {
     //在這裏配置相關的簽名信息
     keyStore {
         storeFile file("test.jks")
         storePassword "111111"
         keyAlias "test"
         keyPassword "111111"
     }
}複製代碼

而後在 buildTypes 中設置簽名信息:

buildTypes {
    release {
        signingConfig signingConfigs.keyStore //設置簽名文件
    }

    debug {
        signingConfig signingConfigs.keyStore  //設置簽名文件
    }
}複製代碼

6. 日誌開關

這個太簡單了,不想單獨列出來。不過上面場景裏面提出來了,就簡單一行代碼展現吧。

release {
    // 不顯示Log
    buildConfigField "boolean", "LOG_DEBUG", "false"
}

debug {
    // 顯示Log
    buildConfigField "boolean", "LOG_DEBUG", "true"
}複製代碼

在日誌工具類中使用 BuildConfig 類中的 LOG_DEBUG 常量來判斷當前是否應該輸出日誌。

固然也能夠用這個開關來控制開啓嚴格模式等其餘只適合在 debug 模式下開啓的設置。

結語

唧唧歪歪說了這麼多,在懂的人眼中天然很簡單,在對 gradle 一點都不瞭解的人眼中就能夠直接複製過去用了。固然我是不建議直接複製,畢竟需求稍微一改,你可能就一籌莫展了。建議你們仍是以理解爲主,掌握其原理天然一通百通。

相關閱讀

Android Studio 3.0 上 Gradle 改動

使用 Gradle 實現一套代碼開發多個應用

歡迎關注微信公衆號: 大腦好餓,更多幹貨等你來嘗

公衆號:大腦好餓
公衆號:大腦好餓
相關文章
相關標籤/搜索