目前在項目中遇到了這樣一種狀況,公司的產品須要在不一樣的機子(本身產品)上進行運行,有的是正常手機 有的是沒有顯示屏的手機,須要另外作處理。那麼如今問題來了,總不可能一個產品一個項目把,那麼咱們就能夠經過productflavors進行代碼多用android
舉一個極端的例子,你家的app賣不出,別人來代理你家的app,說圖標要換成他家的,那麼你怎麼辦?總不可能直接拿項目改把,萬一又說不要你家app了呢?(開個玩笑)git
步驟: 先將android studio的目錄結構改爲project github
在與main同級下新建一個目錄 我這裏叫seller bash
tips1:這裏說明一下,在res目錄下的替換都是批量替換,在main目錄的strings.xml裏面確定不止一個strings,咱們在seller的strings.xml下新建一個appname 並更改了值 那麼只有這個appname會被替換 其餘的仍是原封不動的使用main的東西 tips2:其餘同理,只要是在res目錄下,都是批量替換(名字必定要同樣 不管是string 仍是圖片)架構
在替換以前 咱們還須要作一些事情,就是聲明 在gradle文件裏面 app
productFlavors {
seller {
}
}
複製代碼
gradle sync以後 在build Variants裏面就能夠看到不一樣的項目了 gradle
你可能會說 如今不就只剩一個了麼,想用原來的代碼不想用seller怎麼辦? 笑哭.jpg 新增一個就好 ui
打包的時候你能夠同時打兩個包 this
在build Variants裏面的選項的做用:你選擇哪一個,運行的時候(debug run)就運行哪一個版本 以上就是素材的替換google
可能某一個部分的機器須要另外的新增的代碼 並且與原來的代碼區別仍是蠻大的 那麼咱們能夠進行代碼的替換
tips1:代碼的替換並非部分替換 而是文件的替換(例如一個mainActivity的替換,而不是mainActivity的某個代碼片斷的替換)
tips2:要替換的代碼的那個文件不能存在於main文件夾內
如今 咱們在seller下新建同樣的代碼結構
如今將origin也複製一遍代碼結構 而且將main文件夾內的刪除
Tips:目前Build Variant是sellerdebug 因此seller下面的文件夾和main文件夾是有顏色的 可是origin沒有,側面說明android studio仍是挺智能的
以上就是代碼的替換 只要你你運行那個分支你就會運行哪裏的代碼(沒有替換的代碼會用main文件夾的)
一些使用心得:若是隻是小部分代碼須要替換 最後仍是在main裏面if else修改 比較方便 否則你就要維護兩套代碼 使用mvp分層的話 能夠儘可能減小文件的替換 維護更少的代碼!!!
若是你在seller中使用一個ip origin使用一個ip 怎麼辦
productFlavors {
seller {
buildConfigField("String", "URL", '"www.baidu.com"')
}
origin{
buildConfigField("String", "URL", '"www.google.com"')
}
}
複製代碼
使用buildConfig字段
String ip = BuildConfig.URL;
複製代碼
這樣這個ip在seller下是baidu 在origin下是google 是自動的
此外 也能夠在debug和release下使用
buildTypes {
debug{
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildConfigField("String", "URL", '"www.baidu.com"')
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildConfigField("String", "URL", '"www.google.com"')
}
}
複製代碼
if (BuildConfig.FLAVOR.equals("seller")) {
//// TODO: 2017/12/7
}
複製代碼
使用flavor字段能夠判斷運行的是哪一個分支 而後進行小範圍的代碼的if else
例如 seller下使用騰訊的sdk 可是origin的使用百度的sdk 難道打包就須要打包兩個sdk???
舉個例子 使用分支的名字加上Compile就能夠只在seller項目中compile這個東東
可是這樣有個問題 若是你在同一套代碼裏面作了if else判斷 若是在某個分支裏面沒有compile這個包 那麼可能會報錯
//舉個例子:demo例子
//若是在seller項目中沒有compile tx的sdk 那麼編譯的時候會報錯 說沒有找到tx sdk這個類
if(flag){
TXSdk.init(this)
}else{
BaiduSdk,init(this)
}
複製代碼
在個人項目中 有一臺手機是沒有屏幕的 可是有一個lcd屏 因此我須要新增邏輯 進行處理 假設這個沒有屏幕的手機是seller項目
seller項目須要compile一個jar包這個jar包很大 由於我是sellerCompile的 在origin中是沒有的 因此我不能在main的代碼中寫入關於這個jar的代碼 否則origin就編譯不起來
那麼我是怎麼辦的呢?
我新增一個receiver 和一個service 經過發intent的方式 若是是seller項目天然能夠收到intent 而且使用jar包的類進行處理(使用jar包的代碼在seller分支裏面 而不是在main裏面) 就沒有問題,若是是origin項目 不會有receiver會收到這個intent 而後就不會處理
因此我是經過receiver進行中轉處理的
項目的demo(只有結構哈):https://github.com/Lemniscate317/ProductFlavorsDemo