一、概述
在Android開發中,我們需要構建不同的版本類型(Relase、Debug、Alpha),或者是不同渠道(豌豆莢、小米、三星等),這些都可以配置編譯變體來實現,本文就是希望通過簡短且概括性的文字來進行解釋。
以下內容均可在Google官方文檔中找到,詳看:配置編譯變體。
二、使用buildTypes構建不同版本類型
什麼叫不同版本類型?根據我的理解就是,Google提供了一系列屬性(參考:版本類型 DSL參考),然後我們可以根據需要爲不同版本配置不同的屬性,從而實現打出來差異化的包。
如果你沒接觸過,你應該會覺得很抽象,舉個例子:
比如說,我要給當前項目構建兩種包(Debug和Release),Debug版本可以支持adb debug,Release版本則不行,同時Debug版本的包名後綴需要在原有基礎上增加“.debug”,那麼我們就可以通過配置buildTypes來實現,代碼如下:
1.修改app目錄下的build.gradle文件
⚠️注意:release版本里面一定要加上簽名,不然打出來的包安裝不了,會提示沒有簽名信息!!簽名過程這裏不贅述了,不懂的同學也是自行搜索。
android {
//...
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// release版本簽名
signingConfig signingConfigs.release
}
debug {
applicationIdSuffix ".debug"
debuggable true
}
}
//...
}
2.同步代碼
一般修改build.gradle後,都會要求你Sync Now,不懂怎麼同步代碼的同學自行搜索。
3.編包
在Teminal執行命令gradlew assemble
,編譯成功會提示如下:
然後打開你的目錄app下的build/apk/目錄,下面多了兩個文件夾,分別是debug和release,裏面分別有兩個apk,如下圖所示。
4.驗證
分別安裝兩個app,我們就可以驗證它們是否滿足我們的要求。
首先安裝debug目錄下的apk,打開調試工具可以看到,包名確實變成了“.debug”結尾,並且是可以調試的。
再來看relase包,安裝後在調試工具看不到對應的可調試app,因爲我們沒有設置它是debuggable,通過pm list packages
命令查看已安裝app,確實有一個com.ryan.testbuildtype
的app,跟debug包的包名是不一樣的。
由此驗證得知,確實可以通過buildTypes來構建不同類型的包,當然,在版本類型 DSL參考裏面提供了很多不同的屬性,如是否可以調試JNI代碼的屬性jniDebuggable
、是否打開Proguard的屬性useProguard
、是否壓縮資源文件的屬性shrinkResources
等,你都可以根據自己的需求來進行構建不同屬性類型的包。
三、使用productFlavors實現多渠道打包
在Google官方的解釋是productFlavors是用以構建不同產品特性使用的,但是國內的開發者都喜歡用以實現多渠道打包,所以本文暫且這麼來寫。
我們都知道通過buildTypes可以實現構建不同屬性的包,但是針對不同類型維度的打包,確實有心無力,怎麼說?
比如,我們需要構建不同區域的包,實現內容是一樣的,但是所有網絡請求的域名隨區域的變化而變化,假如我們在代碼中通過if-else來實現,會顯得非常冗餘,下面就以這個例子來講解productFlavors的使用。
1.首先在app目錄下的build.gradle文件增加productFlavors屬性
首先需要定義一個flavorDimensions,例如我定義的是location作爲區分維度。假如你有多個維度,那麼最終就會構建出來幾個維度多種組合的包。
android {
// ...
// 特性維度
flavorDimensions "location"
productFlavors {
guangzhou{
dimension "location"
}
chengdu {
dimension "location"
}
}
// ...
}
2.同步代碼
3.在src目錄創建對應flavor的目錄
如我們要根據地區,構建不同的ip地址,那麼我們就可以把ip定義到java文件裏面,在app目錄下的src目錄,右鍵new->Folder->Java Folder,然後選擇對應的flavors,如本例中的guangzhou,就會生成一個guangzhou的目錄,然後在java目錄下新建一個包名(這個是必須要的),然後創建一個文件,如下圖所示:
然後在裏面定義廣州的域名:
public class MyConstants {
public static final String DOMAIN = "http://www.guangzhou.com";
}
同樣地,創建成都的目錄,並創建同樣的包名和類名,並創建同樣的變量:
public class MyConstants {
public static final String DOMAIN = "http://www.chengdu.com";
}
也許你的java文件變成了紅色,如下圖所示:
不用擔心,只是你當前的flavor是廣州而已,選擇as左下角的Build Variants,切換到成都的flavor,你的文件就是正常的類了。
4.在main目錄下的文件引用不同flavor的屬性
爲了測試方便,我們就在MainActivity中打印MyConstants的值即可,代碼如下所示:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.tv_text);
textView.setText(MyConstants.DOMAIN);
}
}
使用teminal打包,構建出兩個flavor的debug包:
分別安裝,可以看到最終打印的域名是不一樣的,從而實現了不同渠道打包:
當然,這只是非常簡單的應用,當你需要進行更大代碼差異化的時候,也可以利用productFlavors來劃分特性,從而可以同時構建出不同渠道的apk,避免在代碼中進行冗雜的if-else判斷。