因為項目中存在多種環境,既要區分bebug與release版本,release又要區分測試環境與生產上線環境,每次打包都得浪費不少的等待時間;並且哪個版本有問題還得去切換環境一個個打包,關鍵是還得牢記每次切換環境需要修改的內容,盡管每次都檢查仔細,但總有可能疏忽的時候,一旦有問題既浪費自己的時間又浪費測試人員的時間;因此不得不去研究一鍵切換環打包的功能
一、區別debug與release
首先在build.gradle中配置簽名信息,為debug配置差異屬性
android { defaultConfig { versionName "v2.2.2" versionCode 20 } signingConfigs { release { storeFile file('/Users/ram/WorkSpace/AndroidWorkSpace/....keystore')//簽名key所在目錄 keyAlias '...' keyPassword '...' storePassword '...' } } buildTypes { release { buildConfigField "Boolean", "isDebug", "false"//參數1:類型 參數2:變量名 參數3:變量值 debuggable false minifyEnabled true //刪除無用代碼 shrinkResources true//刪除無用資源 zipAlignEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release//簽名 } debug { buildConfigField "Boolean", "isDebug", "true"//參數一:類型,參數二:變量名,參數三:變量值 debuggable true // debug模式下,顯示log versionNameSuffix "-debug" // 為版本名添加后綴 minifyEnabled false zipAlignEnabled false shrinkResources false } }
簽名文件及其他通用代碼應該都會熟悉,這里主要區別定義的一個常量
buildConfigField "Boolean", "isDebug", "false"//參數一:類型,參數二:變量名,參數三:變量值
這是用於區別是否調試版本,用於是否打印log日志時所用,java中調用方式:
public static final boolean isDebug = BuildConfig.isDebug;
在代碼中就可以通過這個值判斷是否需要開啟Log;還有一個versionNameSuffix "-debug",這個是我的項目中需要顯示版本號,在versionName后追加了一個名稱,用以區分
二、多渠道區分,配置不同產品的差異屬性
同樣是在grdle中android{}目錄里面添加
productFlavors {//設置不同產品的特性 uat {//測試環境 buildConfigField "String", "HOST", "\".....\"" versionName "v2.2.2.2" } prod {//正式上線環境 buildConfigField "String", "HOST", "\".....\"" versionName "v2.2.2" } }
這里配置兩個不同產品渠道,根據自己的需求可增加刪除,其中buildConfigField "String", "HOST", "\".....\""
同上面isDebug一樣是根據環境差異增加的一個常量,我這里是用於訪問服務器的地址更改;根據自己需求也可以增刪改,這里要注意的是第三個參數字符串的雙引號需要用轉義字符;
同樣在java中的調用方法:
public static final String ROOTHOST = BuildConfig.HOST; 其中versionName是對版本號名稱的重命名,這是我項目中對不同環境做版本號區分所用;
三、打包apk文件的重命名
繼續在grdle中android{}目錄里面添加
//apk文件重命名 applicationVariants.all { variant -> variant.outputs.all { def fileName = "xxx-" + versionName + ".apk" outputFileName = fileName // output -> output.outputFileName = "NYTalk_" + buildType.name + "_" + defaultConfig.versionName + "_" //+ new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC")) + ".apk" } }
這個是用於打包的時候根據自己的需求重命名apk,簡單點就自己項目名稱加版本號,需要時間等其他參數也可用注釋掉的代碼,或者自行個更改;需要注意的是defaultConfig.versionName調用的是開始默認的versionName,需要用自己后面修改過的versionName命名,不加defaultConfig即可;
四、assets資源目錄做區分
前面主要做的區分都是一些java代碼可調用的變量;那么原生assets資源目錄如何根據環境做區分:
1.項目結構視圖調整為project,在src目錄下,mian的同級目錄創建uat與prod文件夾(根據productFlavors自己定義的不同產品渠道創建),並創建assets資源目錄,這里資源目錄里就可以放置不同渠道的同名不同資源,例如:
2.然后繼續在grdle中android{}目錄里面根據flavors指向定義的資源目錄
sourceSets { assets.srcDirs = ['src/assets'] uat{ assets.srcDirs = ['src/ust/assets'] } prod { assets.srcDirs = ['src/prod/assets'] } }
差異的資源根據產品做區分存放,通用的assets資源按原來的存放方式不變
3.不過我的項目因為是以前的eclipse遷移過來的,src下直接存放是java代碼,res與src是同級目錄,所以我這里創建的uat與prod文件夾是與src、res同級的,然后在gradle中的配置如下:
sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] jniLibs.srcDirs = ['libs'] } uat{ assets.srcDirs = ['uat/assets'] } prod { assets.srcDirs = ['prod/assets'] } }
五、環境一鍵切換,更改Build variants中相應即可,運行手機上切換平台就行
六、一鍵打包不同平台的apk
Gradle---項目名稱下的Tasks---build---assemble,也可以根據不同的assemble生成特定apk
編譯生成的apk在build--outputs下查看:
打包好的apk可以自行驗證assets資源是否是對應的平台資源,可直接解壓apk文件查看