Android多環(huán)境編譯打包

在開發(fā)App時,經(jīng)常需要切換開發(fā)環(huán)境,最常用的就是開發(fā)環(huán)境(測試服務(wù)器)和生產(chǎn)環(huán)境(正式服務(wù)器),更保險的,則會在上線前,會先在預(yù)發(fā)布(生產(chǎn)環(huán)境克隆版)環(huán)境跑一遍。

不同環(huán)境之間,簽名、包名、服務(wù)器地址、應(yīng)用名稱、圖標(biāo)可能都不一樣。手動切換環(huán)境不僅麻煩而且易出錯。

為什么不同的環(huán)境要使用不同的applicationId、應(yīng)用名稱甚至圖標(biāo)呢,如果你遇到測試向你抱怨,在同一臺設(shè)備上反復(fù)安裝卸載app,只是為了切換環(huán)境,有時候自己都搞不清出安裝的是哪個環(huán)境app時,你就會懂的這做多么有用。

這里詳細(xì)講幾種多環(huán)境打包編譯的方式。

一個環(huán)境一個分支

比如master就是開發(fā)分支,preview是預(yù)發(fā)布環(huán)境分支,release是生產(chǎn)環(huán)境分支。

不同分支之間,在上線時只有環(huán)境相關(guān)的代碼或者配置是不一樣的。

假設(shè)我們上線的流程是開發(fā)->測試->預(yù)發(fā)布->生產(chǎn),在測試完成后,將master的改動合并到preview分支上,然后切換到preview分支打包預(yù)發(fā)布環(huán)境的安裝包。通過測試后再合并到release,編譯并上線完成。

需要注意的問題:不同分支之間,在代碼合并時要特別注意不要將環(huán)境配置合并了。

使用gradle配置

打開app/build.gradle文件,找到buildTypes,默認(rèn)有debug和release兩個編譯版本,我們添加了第三種:preview。

使用React Native的同學(xué)請注意
新增一個buildTypes,如果名字不是releaseXXX或則會debugXXX,jsbundle將不會被打包到apk中。
React Native工程中的app/build.gralde寫在前面的注釋中有這么一段:

 *   // whether to bundle JS and assets in another build variant (if configured).
 *   // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
 *   // The configuration property can be in the following formats
 *   //         'bundleIn${productFlavor}${buildType}'
 *   //         'bundleIn${buildType}'
 *   // bundleInFreeDebug: true,
 *   // bundleInPaidRelease: true,
 *   // bundleInBeta: true,

也就是說,如果我們要引入名為preview的buildTypes,需要加入這么一段:

project.ext.react = [
    entryFile: "index.js",
    // 添加
    bundleInPreview: true
]

在buildTypes和productFlavors中,我們多種方式個性化編譯配置。以下是我經(jīng)常用到的幾種:

  • applicationId 可以在buildTypes中指定新的,覆蓋defaultConfig中的設(shè)置
  • applicationIdSuffix 給applicationId添加后綴,比如.dev這樣的
  • manifestPlaceholders 此處定義的內(nèi)容,可以在清單文件AndroidManifest.xml中使用,比如android:label="${app_name}"
  • buildConfigField 定義后可以通過BuildConfig.xxx使用
  • resValue 跟在xml中定義的量一樣,注意不要重復(fù)沖突就行,在Java中通過getResources().getString(R.string.app_name)之類的方式拿到,在xml(如布局)中可以通過@string/app_name引用。
  • 可以通過gradle.properties設(shè)置環(huán)境變量,如定義簽名文件MYAPP_RELEASE_STORE_FILE=my-release-key.keystore,則可以在signingConfig 中使用storeFile file(MYAPP_RELEASE_STORE_FILE)。

下面是示例:

多版本打包

    buildTypes {
        debug {
            // applicationId添加后綴
            //比如defaultConfig中設(shè)置的applicationId為com.example.myapp
            //編譯debug版本時applicationId將是com.example.myapp.dev
            applicationIdSuffix ".dev"
            manifestPlaceholders = [
                    app_name: "myApp-dev",
                    app_icon: "@drawable/icon_deve"
            ]
            //開發(fā)服務(wù)器地址
            buildConfigField "String", "BASE_URL", '"https://dev.example.com/api"'  
            //開發(fā)環(huán)境 極光推送的AppKey
            buildConfigField "String", "JPUSH_APP_KEY", '"xxxxxx"' 
            signingConfig signingConfigs.debug
        }
        release {
            applicationIdSuffix ".prod"
            manifestPlaceholders = [
                    app_name: "myApp",
                    app_icon: "@drawable/icon_prod"
            ]
            //生產(chǎn)服務(wù)器地址
            buildConfigField "String", "BASE_URL", '"https://prod.example.com/api"'    
            //生產(chǎn)環(huán)境 極光推送的AppKey
            buildConfigField "String", "JPUSH_APP_KEY", '"xxxxxx"' 
            signingConfig signingConfigs.release
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
        preview {
            applicationIdSuffix ".preview"
            manifestPlaceholders = [
                    app_name: "myApp-preview",
                    app_icon: "@drawable/icon_prod"
            ]
            //預(yù)覽版服務(wù)器地址
            buildConfigField "String", "BASE_URL", '"https://preview.example.com/api"'    
            //預(yù)覽環(huán)境 極光推送的AppKey
            buildConfigField "String", "JPUSH_APP_KEY", '"xxxxxx"' 
            // 子模塊沒有preview時,則會匹配release
            matchingFallbacks = ['release']
            signingConfig signingConfigs.release
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }

多渠道打包

    // 類型維度
    flavorDimensions "myapp"
    productFlavors {
        // 官網(wǎng)下載渠道
        official {
            //自定義資源,類似在strings.xml中配置的
            //Java中使用 getResources().getString(R.string.channel)
            //xml中使用 android:text="@string/channel"
            resValue "string", "channel", "official"
        }
        //應(yīng)用寶下載渠道
        tencent {
            resValue "string", "channel", "tencent_market"
        }
    }

如果想編譯preview版本的apk,則可以

./gradlew assemblePreview

編譯完成后apk保存在app/build/outputs/apk中,由于我們定義了兩個變體(productFlavors),因此將輸出兩個變體版本的apk,存儲路徑是app/build/outputs/apk/{productFlavor}${buildType},一個channel值為official的官網(wǎng)渠道版本,另一個是值為tencent的應(yīng)用包渠道版本。

如果只想編譯一種變體,可以執(zhí)行

./gradlew assembleOfficialPreview

完結(jié)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容