一.組件化簡(jiǎn)介
注:組件化開發(fā)只適用于大型團(tuán)隊(duì)協(xié)作開發(fā)大型項(xiàng)目的場(chǎng)景酿愧,如果只是個(gè)人或者兩三人開發(fā)則沒有必要使用
什么是組件化
業(yè)務(wù)按照功能劃分為一個(gè)一個(gè)模塊,模塊之間沒有依賴關(guān)系偎巢,相互平行顽馋,模塊之間的通信通過一定技術(shù)手段實(shí)現(xiàn)的開發(fā)方式就叫組件化
為什么需要組件化皱碘?
傳統(tǒng)的開發(fā)方式:多人協(xié)作開發(fā)同一個(gè)項(xiàng)目,代碼雜亂不易管理均唉,并且多個(gè)功能之間依賴程度較高是晨,無法做到按功能分組來打包提測(cè),必須同步進(jìn)行舔箭,有可能開發(fā)周期較短的功能需要等待開發(fā)周期較長(zhǎng)的功能罩缴,效率較低
組件化開發(fā)方式:各功能之間互不影響,獨(dú)立進(jìn)行层扶,并且可以實(shí)現(xiàn)單獨(dú)模塊打包箫章,一個(gè)模塊的進(jìn)度不會(huì)影響到另一個(gè)模塊的進(jìn)展,有效的提高了開發(fā)測(cè)試的效率镜会,代碼結(jié)構(gòu)清晰檬寂,便于管理。
組件化的實(shí)現(xiàn)方式
上邊提到組件化各模塊之間相互不允許有依賴關(guān)系稚叹,那么模塊之間的通信方式就是一個(gè)需要首先解決的問題焰薄。通常來說實(shí)現(xiàn)方式有下面幾種:
1.EventBus(每一個(gè)消息傳遞都需要一個(gè)獨(dú)立的EventBean,維護(hù)成本太高)
2.廣播 (不好管理,都統(tǒng)一發(fā)出去了)
3.使用隱士意圖方式(在AndroidManifest.xml里面配置xml寫的太多了)
4.使用類加載方式 (除了容易寫錯(cuò)包名類名之外扒袖,其他缺點(diǎn)較少)
5.使用全局Map的方式(要在Application中注冊(cè)很多的對(duì)象塞茅,太費(fèi)事)
6.ARouter目前應(yīng)用最廣的方式 ARouter
ARouter由阿里巴巴開源(https://github.com/alibaba/ARouter)
二.這篇文章不去關(guān)注如何使用ARouter,而是重點(diǎn)放在組件化基礎(chǔ)配置的搭建上
1.實(shí)現(xiàn)組件獨(dú)立打包
既然是搭建組件化項(xiàng)目,那么首先我們要分出幾個(gè)功能模塊來!創(chuàng)建一個(gè)工程季率,app為項(xiàng)目主模塊野瘦,然后創(chuàng)建另外三個(gè)Module:home,mine飒泻,news鞭光,最后創(chuàng)建一個(gè)Library庫作為最底層的基礎(chǔ)庫
他們的依賴關(guān)系是這樣的
app
implementation project(':mine')
implementation project(':home')
implementation project(':news')
mine
implementation project(':library')
home
implementation project(':library')
news
implementation project(':library')
創(chuàng)建一個(gè)common.gradle文件做全局的一些配置
然后在項(xiàng)目根目錄的build.gradle中引入這個(gè)文件
common.gradle
ext {
isRelease = true
}
定義一個(gè)isRelease變量來作為項(xiàng)目的環(huán)境配置,我們要實(shí)現(xiàn)泞遗,線上環(huán)境打包把所有模塊都打進(jìn)去惰许,測(cè)試環(huán)境打包可以指定模塊單獨(dú)打包
那么怎么實(shí)現(xiàn)呢?
我們知道史辙,每個(gè)module要單獨(dú)能夠打包的話汹买,他就必須有這樣一個(gè)配置佩伤,也就是說它必須是一個(gè)module而不是一個(gè)library
apply plugin: 'com.android.application'
那么我們就可以通過isRelease這個(gè)變量來if else判斷了,我們?cè)诿總€(gè)組件的build.gradle文件頂部配置如下:
if (isRelease) {
apply plugin :'com.android.library'
} else {
apply plugin: 'com.android.application'
}
android {
...
defaultConfig {
if (!isRelease) { // 能夠獨(dú)立運(yùn)行 必須要有applicationId
applicationId "com.renzhenming.xxxx"
}
....
}
}
也就是說release環(huán)境下晦毙,這個(gè)組件作為library被app依賴生巡,debug環(huán)境下,這個(gè)組件是一個(gè)單獨(dú)的module见妒,可以實(shí)現(xiàn)獨(dú)立打包孤荣。這樣一來我們mine home news 三個(gè)module下都配置好了
然后在app build.gradle下配置如下,只有release環(huán)境下才去依賴三個(gè)library
dependencies {
...
if (isRelease){
implementation project(':mine')
implementation project(':home')
implementation project(':news')
}
}
如此,只是通過改變common.gradle文件中的isRelease字段的值就可以控制是否進(jìn)行模塊打包了须揣,我們將isRelease設(shè)置為false盐股,然后編譯下看看,可以看到home,mine返敬,news三個(gè)組件可以單獨(dú)打包了
然后把isRelease設(shè)置為true再次編譯
2.組件獨(dú)立打包如何運(yùn)行
僅僅是獨(dú)立打包是不行的遂庄,總要有一個(gè)啟動(dòng)的Activity吧,但是這個(gè)Activity在release環(huán)境下又不能讓他起作用劲赠,也就是不能在組件的AndroidManifest中配置,那么我們是不是可以指定一個(gè)debug環(huán)境下的AndroidManifest文件呢秸谢?
當(dāng)然是可以的凛澎,我們?cè)诿總€(gè)組件的src/main下創(chuàng)建一個(gè)debug目錄和一個(gè)AndroidManifest,在這里指定LAUNCHER Activity
在這個(gè)組件的build.gradle下配置debug環(huán)境時(shí)文件AndroidManifest的目錄指向我們創(chuàng)建的這個(gè)AndroidManifest
android {
...
sourceSets {
main {
if (!isRelease) {
// 如果是組件化模式
manifest.srcFile 'src/main/debug/AndroidManifest.xml' // 生效
} else { // 正式環(huán)境下
manifest.srcFile 'src/main/AndroidManifest.xml' // 讓我們之前 默認(rèn)的路徑下的清單文件再次生xiao
}
}
}
}
但是有一個(gè)問題估蹄,這個(gè)debug目錄既然時(shí)測(cè)試環(huán)境打包用的塑煎,release環(huán)境我們肯定不希望它的代碼被打進(jìn)包里去,那么release的時(shí)候我們就要把這個(gè)目錄移除臭蚁,添加一行配置
android {
...
sourceSets {
main {
if (!isRelease) {
// 如果是組件化模式
manifest.srcFile 'src/main/debug/AndroidManifest.xml' // 生效
} else { // 正式環(huán)境下
manifest.srcFile 'src/main/AndroidManifest.xml' // 讓我們之前 默認(rèn)的路徑下的清單文件再次生xiao
java {
// release 時(shí) debug 目錄下文件不需要合并到主工程
exclude "**/debug/**"
}
}
}
}
}