最近遇到這樣一個需求:一套代碼須要給不一樣的公司打包,須要修改App icon,ic_launcher,歡迎頁背景圖,登陸按鈕顏色,第三方的不一樣的key,包名,applicationId等java
做爲一個懶得不想動的程序員,是不可能去給每一個公司打一個包的,因此把精力放到了多渠道打包的想法上。android
通過研究最終實現思路是這樣的。程序員
在app的model下建立了幾個不一樣的文件夾。層級以下:api
flavor_xxx爲新建的目錄,每一個目錄下包括一些資源,資源的相同點(不一樣apk下不一樣的東西:好比App icon,背景圖等),它們必須是與app的model下資源的名字是相同的,以下圖:(res->mipmap-hdpi->ic_launcher.phg與app model下的資源路徑是相同的)微信
values下的strings.xml裏的內容是不一樣的App名稱,公司名稱,電話號碼等app
第一步完成,接下來須要在app.build 中配置一下。測試
android { compileSdkVersion 25 buildToolsVersion '25.0.0' signingConfigs { def alias = 'keystory alias' def password = 'keystory possword' def filePath = 'keystore/xxx.jks' debug { keyAlias alias keyPassword password storeFile file(filePath) storePassword(password) } 1{ storeFile file(filePath) keyAlias alias keyPassword password storePassword(password) } 2{ keyAlias alias keyPassword password storeFile file('keystore/xxx.jks') storePassword(password) } 3{ keyAlias alias keyPassword password storeFile file('keystore/xxx.jks') storePassword(password) } 4{ keyAlias alias keyPassword password storeFile file('keystore/xxx.jks') storePassword(password) } 5{ keyAlias alias keyPassword password storeFile file('keystore/xxx.jks') storePassword(password) } } defaultConfig { applicationId "com.lesoft.wuye" minSdkVersion 15 targetSdkVersion 23 versionCode 255 versionName "2.5.5" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true ndk { abiFilters "armeabi-v7a" } } productFlavors { flavor_1 { applicationId = "com.xxx"
// manifestPlaceholders中寫到的『BAIDU_KEY』
// 這裏所設置的變量能夠直接使用在『AndroidManifest.xml』中,使用方式爲:${package_name}
//
android:name="${HOST}.permission.JPUSH_MESSAGE"
// <meta-data
// android:name="com.baidu.lbsapi.API_KEY"
// android:value="${BAIDU_KEY}"/>
manifestPlaceholders = [BAIDU_KEY : "", JPUSH_APPKEY: "", UMENG_APPKEY: "", HOST: applicationId] } // flavor_2 { // applicationId = "com.xxx" // manifestPlaceholders = [BAIDU_KEY : "百度key", // JPUSH_APPKEY: "極光推送key", // UMENG_APPKEY: "友盟", HOST: applicationId] // } // flavor_3 { // applicationId = "com.xxx" // manifestPlaceholders = [BAIDU_KEY : "", // JPUSH_APPKEY: "", // UMENG_APPKEY: "", HOST: applicationId] // // } // // flavor_4 { // applicationId = "com.xxx" // manifestPlaceholders = [BAIDU_KEY : "", // JPUSH_APPKEY: "", // UMENG_APPKEY: "", HOST: applicationId] // } // // flavor_5 { // applicationId = "com.xxx" // manifestPlaceholders = [BAIDU_KEY : "", // JPUSH_APPKEY: "", // UMENG_APPKEY: "", HOST: applicationId] // } } buildTypes { debug { // 若是 debug 包須要測試諸如微信、地圖等第三方 sdk ,則能夠指定 debug 包使用 release 包的簽名 //debug 並不能設置多個簽名 debuggable true minifyEnabled false productFlavors.flavor_1.signingConfig signingConfigs.1 // //爲已經存在的applicationId添加後綴 // applicationIdSuffix ".debug" // // 爲版本名添加後綴 // versionNameSuffix "-debug" } release { minifyEnabled false
// shrinkResouse ture 移除無用資源 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' // productFlavors.flavor_1.signingConfig signingConfigs.1 // productFlavors.flavor_2.signingConfig signingConfigs.2 // productFlavors.flavor_3.signingConfig signingConfigs.3 // productFlavors.flavor_4.signingConfig signingConfigs.4 // productFlavors.flavor_5.signingConfig signingConfigs.5 applicationVariants.all { variant -> variant.outputs.each { output -> def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith('.apk')) { //輸出apk名稱爲:渠道名_版本名_時間.apk def fileName = "${variant.productFlavors[0].name}_v${defaultConfig.versionName}_${releaseTime()}.apk" output.outputFile = new File(outputFile.parent, fileName) } } } } } }
最後在AndroidManifest.xml 中加入 <applicationui
android:replace="icon,lable,theme">debug
若是沒有會在編譯中報錯,錯誤以下:3d
到如今多渠道打包就已經配置完成,使用方法:點assembleRelease便可打包,運行速度有點慢。
踩過的坑:在rearelease{
shrinkResources true //移除無用資源
}
若是存在這個配置,會致使把咱們的無用資源給移除,會致使編譯不經過。
在java代碼中須要改的內容是不能在咱們flaflavor_xxx的文件下修改的,須要咱們在代碼中根據App name或者package name來自動判斷。如修改一個登錄按鈕的顏色:
/** * 根據App的名字,若是是xxx公司:登陸按鈕顏色要變 */ private void setLoginBtnColor(){ String app_name = getResources().getString(R.string.app_name); if (app_name.equals("app name")) { mLoginBtn.setBackgroundColor(getResources().getColor(R.color.gaodi_login_btn)); ivPhoto.setImageResource(R.mipmap.ic_launcher_trans); } }