Gradle排除依賴模塊的某個類

好久沒寫文章了,開工第一天來一發開門紅。既然沒什麼可寫的,就簡單聊聊Gradlew吧,是Gradle,命令敲多了習慣加個w,開個小玩笑。gradle用來構建項目可謂是十分的靈活,剛開始接觸也許覺得有點懵,覺得這個東西就是多餘的,但是用多了就真的會愛上它。
我之前做組件化的時候就碰到鍋這樣一個問題,怎麼排除某個類

Gradle怎麼排除所依賴的模塊的某各類

其實我覺得在很多的情況下都會碰到這個問題,比如你的老大寫了個BaseModule,裏面有很多東西,你就沒必要造輪子了,但是其實你這個項目中用不到這麼多,那就沒必要在打包的時候也把多餘的代碼打進去,但是你又不能刪掉,因爲很多個模塊都依賴這個Base模塊,所以你只能用“排除”的方法來去掉多餘的代碼。再比如你自己的模塊和所依賴的模塊有同名類,包名都相同的那種,那就肯定編譯不過,所以你要排除相同類。甚至還有很多情況需要你在依賴中排除某個類或者某個包。
那麼該怎麼做?
只要稍微用過gradle構建項目的都知道,如果我們在依賴時出現了相同的jar包,我們是可以排除的

implementation fileTree(include: ['*.jar'], dir: '../balabala/balabala', exclude: ['重複包1.jar', '重複包2.jar'])

這樣確實能排除某個jar包來達到解決jar包重複的問題,但是用這種方法你能排除到某個類嗎?不能。
比如一般新手寫依賴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插件的東西,他能把代碼文件導入到相應的地方,無論是絕對路徑還是相對路徑,我之前有寫過一篇sourceSets的文章,獲取網上也能找到很多關於sourceSets的文章,你把目標Module的java、res、lib等引進來,即使不使用implementation project的方法,也能讓這個module能夠獲取到目標module的東西。而且使用sourceSets的話可以很方便的exclude某個文件。
但是我覺得這樣的方法不應該叫做“依賴”,更應該叫做“引用”或者“導入”。
所以這種方法更像是一種對文件的操作,copy的感覺,所以這種方法也就有了不足的地方,假如你在某種情況下需要引用ModuleA,某種情況下引用ModuleB,要麼你就加個判斷,要麼就每次都改代碼,要是有兩個還好說,要是有20幾個Module呢?我們總不能這樣玩吧,就算是能,當你每次在gradle中看到這段代碼時,相信你也會老闊疼。

方案二:在目標模塊就進行排除代碼

什麼意思呢?比如說你想要依賴ModuleA,但是又想排除某些文件,我們可以直接在ModuleA中進行排除,意思是你依賴的ModuleA就已經少了你想排除的代碼。
這樣做的話可以讓依賴的那一方不用考慮特殊情況,雖然像上面說的情況多的時候也要寫挺多代碼,但是這些邏輯會很清晰,很容易管理,我個人更傾向於使用這樣的方法也排除單個文件。哪怕最上面說的implementation project時exclude能夠實現,我依舊更傾向於在某塊本身進行排除。
但是我們要怎樣控制呢,難道每次都要去修改多個gradle文件嗎?其實在gradle中我們可以使用全局變量。

1.創建一個config.gradle寫變量
// 配置全局變量
ext{
    configOne = [isRealy:true]
}

假設我這樣有一種情況,叫configOne ,這種情況下isRealy這個值是true,這種情況下我們要在引用模塊時排除掉某個類。

2.在全局gradle中引用config.gradle
apply from: 'config.gradle'
......
3.在目標gradle中加入構建邏輯

假如我的目標模塊 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這樣就行了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章