android 一套代碼多用 以及 多套代碼用於一個項目

文章關鍵字 productFlavors

目前在項目中遇到了這樣一種狀況,公司的產品須要在不一樣的機子(本身產品)上進行運行,有的是正常手機 有的是沒有顯示屏的手機,須要另外作處理。那麼如今問題來了,總不可能一個產品一個項目把,那麼咱們就能夠經過productflavors進行代碼多用android

項目使用mvp架構 demo也是以此爲前提

第一種狀況,代碼不變,素材變化

舉一個極端的例子,你家的app賣不出,別人來代理你家的app,說圖標要換成他家的,那麼你怎麼辦?總不可能直接拿項目改把,萬一又說不要你家app了呢?(開個玩笑)git

步驟: 先將android studio的目錄結構改爲project github

image.png

在與main同級下新建一個目錄 我這裏叫seller bash

image.png
而且根據main目錄的目錄結構(必定要同樣),新建res 新建values 新建strings.xml
image.png
並將原來的appname 在後面加上111

tips1:這裏說明一下,在res目錄下的替換都是批量替換,在main目錄的strings.xml裏面確定不止一個strings,咱們在seller的strings.xml下新建一個appname 並更改了值 那麼只有這個appname會被替換 其餘的仍是原封不動的使用main的東西 tips2:其餘同理,只要是在res目錄下,都是批量替換(名字必定要同樣 不管是string 仍是圖片)架構

在替換以前 咱們還須要作一些事情,就是聲明 在gradle文件裏面 app

image.png
新增一個productFlavors 裏面聲明一個seller

productFlavors {
        seller {
        }
    }
複製代碼

gradle sync以後 在build Variants裏面就能夠看到不一樣的項目了 gradle

image.png

image.png

你可能會說 如今不就只剩一個了麼,想用原來的代碼不想用seller怎麼辦? 笑哭.jpg 新增一個就好 ui

image.png
新增一個空的origin

image.png
聲明一下
image.png

打包的時候你能夠同時打兩個包 this

image.png

image.png

在build Variants裏面的選項的做用:你選擇哪一個,運行的時候(debug run)就運行哪一個版本 以上就是素材的替換google

第二種狀況代碼的替換

可能某一個部分的機器須要另外的新增的代碼 並且與原來的代碼區別仍是蠻大的 那麼咱們能夠進行代碼的替換

tips1:代碼的替換並非部分替換 而是文件的替換(例如一個mainActivity的替換,而不是mainActivity的某個代碼片斷的替換)

tips2:要替換的代碼的那個文件不能存在於main文件夾內

如今 咱們在seller下新建同樣的代碼結構

image.png
並把MainActivity文件複製過來

image.png
並將Build Variant設置成sellerdebug

image.png
你會發現報錯 因此說替換代碼的時候main 文件夾內不能存在那個文件

如今將origin也複製一遍代碼結構 而且將main文件夾內的刪除

image.png
再也不報錯

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 是自動的

此外 也能夠在debugrelease下使用

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

項目的compile

例如 seller下使用騰訊的sdk 可是origin的使用百度的sdk 難道打包就須要打包兩個sdk???

image.png

舉個例子 使用分支的名字加上Compile就能夠只在seller項目中compile這個東東

可是這樣有個問題 若是你在同一套代碼裏面作了if else判斷 若是在某個分支裏面沒有compile這個包 那麼可能會報錯

//舉個例子:demo例子
//若是在seller項目中沒有compile tx的sdk 那麼編譯的時候會報錯 說沒有找到tx sdk這個類
if(flag){
  TXSdk.init(this)
}else{
  BaiduSdk,init(this)
}
複製代碼

ui同樣的狀況下 新增代碼邏輯

在個人項目中 有一臺手機是沒有屏幕的 可是有一個lcd屏 因此我須要新增邏輯 進行處理 假設這個沒有屏幕的手機是seller項目

seller項目須要compile一個jar包這個jar包很大 由於我是sellerCompile的 在origin中是沒有的 因此我不能在main的代碼中寫入關於這個jar的代碼 否則origin就編譯不起來

那麼我是怎麼辦的呢?

image.png

我新增一個receiver 和一個service 經過發intent的方式 若是是seller項目天然能夠收到intent 而且使用jar包的類進行處理(使用jar包的代碼在seller分支裏面 而不是在main裏面) 就沒有問題,若是是origin項目 不會有receiver會收到這個intent 而後就不會處理

因此我是經過receiver進行中轉處理的

以上就是我在項目中遇到的一些問題 以及productFlavor的一些使用 固然 productFlavor還有其餘的一些用法 你們能夠本身去了解一下

項目的demo(只有結構哈):https://github.com/Lemniscate317/ProductFlavorsDemo

相關文章
相關標籤/搜索