好久沒寫文章了唉俗,開工第一天來一發(fā)開門紅。既然沒什么可寫的娱仔,就簡單聊聊Gradlew吧沐飘,是Gradle,命令敲多了習(xí)慣加個w,開個小玩笑耐朴。gradle用來構(gòu)建項目可謂是十分的靈活借卧,剛開始接觸也許覺得有點懵,覺得這個東西就是多余的筛峭,但是用多了就真的會愛上它铐刘。
我之前做組件化的時候就碰到鍋這樣一個問題,怎么排除某個類
Gradle怎么排除所依賴的模塊的某各類
其實我覺得在很多的情況下都會碰到這個問題蜒滩,比如你的老大寫了個BaseModule滨达,里面有很多東西,你就沒必要造輪子了俯艰,但是其實你這個項目中用不到這么多捡遍,那就沒必要在打包的時候也把多余的代碼打進去,但是你又不能刪掉竹握,因為很多個模塊都依賴這個Base模塊画株,所以你只能用“排除”的方法來去掉多余的代碼。再比如你自己的模塊和所依賴的模塊有同名類啦辐,包名都相同的那種谓传,那就肯定編譯不過,所以你要排除相同類芹关。甚至還有很多情況需要你在依賴中排除某個類或者某個包续挟。
那么該怎么做?
只要稍微用過gradle構(gòu)建項目的都知道侥衬,如果我們在依賴時出現(xiàn)了相同的jar包诗祸,我們是可以排除的
implementation fileTree(include: ['*.jar'], dir: '../balabala/balabala', exclude: ['重復(fù)包1.jar', '重復(fù)包2.jar'])
這樣確實能排除某個jar包來達到解決jar包重復(fù)的問題,但是用這種方法你能排除到某個類嗎轴总?不能直颅。
比如一般新手寫依賴module都會這樣寫
implementation project(':testModule')
然后你想排除這個模塊中的Test.java 這個文件,你能這樣寫嗎怀樟?
implementation project(':testModule',exclude:['Test.java'])
或者
implementation project(':testModule'){
exclude :'Test.java'
}
這樣寫肯定不行功偿,可能閉包的寫法寫錯了,我也不太記得這個的閉包怎么弄來著往堡,好像是
implementation(project(':testModule')) {
exclude group: 'com.xxx.xxx.Test.java', module: 'testModule'
}
還是這個來著
implementation(project(':testModule'){
exclude group: 'com.xxx.xxx.Test.java', module: 'testModule'
})
但是這樣的做法能排除掉掉這個Test.java嗎械荷?我試過是不行的,如果有朋友能用這種方法排除單個文件請告訴我虑灰。
既然這種方法沒辦法排除類养葵,那么要怎么做?
方案一:放棄implementation project瘩缆,使用sourceSets
sourceSets是java插件的東西,他能把代碼文件導(dǎo)入到相應(yīng)的地方佃蚜,無論是絕對路徑還是相對路徑庸娱,我之前有寫過一篇sourceSets的文章着绊,獲取網(wǎng)上也能找到很多關(guān)于sourceSets的文章,你把目標(biāo)Module的java熟尉、res归露、lib等引進來,即使不使用implementation project的方法斤儿,也能讓這個module能夠獲取到目標(biāo)module的東西剧包。而且使用sourceSets的話可以很方便的exclude某個文件。
但是我覺得這樣的方法不應(yīng)該叫做“依賴”往果,更應(yīng)該叫做“引用”或者“導(dǎo)入”疆液。
所以這種方法更像是一種對文件的操作,copy的感覺陕贮,所以這種方法也就有了不足的地方堕油,假如你在某種情況下需要引用ModuleA,某種情況下引用ModuleB肮之,要么你就加個判斷掉缺,要么就每次都改代碼,要是有兩個還好說戈擒,要是有20幾個Module呢眶明?我們總不能這樣玩吧,就算是能筐高,當(dāng)你每次在gradle中看到這段代碼時搜囱,相信你也會老闊疼。
方案二:在目標(biāo)模塊就進行排除代碼
什么意思呢凯傲?比如說你想要依賴ModuleA犬辰,但是又想排除某些文件,我們可以直接在ModuleA中進行排除冰单,意思是你依賴的ModuleA就已經(jīng)少了你想排除的代碼幌缝。
這樣做的話可以讓依賴的那一方不用考慮特殊情況,雖然像上面說的情況多的時候也要寫挺多代碼诫欠,但是這些邏輯會很清晰涵卵,很容易管理,我個人更傾向于使用這樣的方法也排除單個文件荒叼。哪怕最上面說的implementation project時exclude能夠?qū)崿F(xiàn)轿偎,我依舊更傾向于在某塊本身進行排除。
但是我們要怎樣控制呢被廓,難道每次都要去修改多個gradle文件嗎坏晦?其實在gradle中我們可以使用全局變量。
1.創(chuàng)建一個config.gradle寫變量
// 配置全局變量
ext{
configOne = [isRealy:true]
}
假設(shè)我這樣有一種情況,叫configOne 昆婿,這種情況下isRealy這個值是true球碉,這種情況下我們要在引用模塊時排除掉某個類。
2.在全局gradle中引用config.gradle
apply from: 'config.gradle'
......
3.在目標(biāo)gradle中加入構(gòu)建邏輯
假如我的目標(biāo)模塊 Moudle->myone中有兩個類OneLog仓蛆、TwoLog睁冬,然后我想在A模塊依賴時這兩個類都有,在B模塊依賴時沒有TwoLog看疙。
在myone的gradle寫
def configOne = rootProject.ext.configOne
android {
.....
sourceSets{
main{
java{
if(configOne.isRealy) {
exclude 'com/example/kylin/myone/TwoLog.java'
}
}
}
}
}
然后我們在A模塊引用時豆拨,把isRealy改成false,在B模塊引用時把isRealy改成true這樣就行了能庆。