Gradle排除依赖模块的某个类

本文探讨了在Gradle项目构建中如何排除不需要的类或包,提供了两种实用方案:一是利用sourceSets进行文件级操作;二是通过在目标模块内部进行代码排除,结合全局变量控制,实现根据不同场景灵活排除特定类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

好久没写文章了,开工第一天来一发开门红。既然没什么可写的,就简单聊聊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这样就行了。

### 如何在 Gradle排除特定版本的依赖项 在处理复杂的项目结构时,可能会遇到不同模块之间存在相同依赖的不同版本的情况。为了避免潜在的问题,在 `build.gradle` 文件中可以通过多种方式精确控制哪些依赖应该被排除。 对于想要排除指定版本的依赖包这一需求来说,可以在声明依赖的时候利用 Groovy 提供的强大语法来进行操作。具体而言: 当定义某个依赖时,可以直接在其内部添加 `exclude` 块来指明要排除的目标。例如,假设有一个来自 `com.example` 组下的名为 `library` 的库,默认会引入 `environment-specific-module` 这个组件,但是这个组件可能存在多个版本,而当前希望只排除其中某一个特定版本,则可以这样做[^1]: ```groovy dependencies { implementation('com.example:library:1.0.0') { exclude group: 'com.example', module: 'environment-specific-module' } } ``` 上述方法适用于已知确切需要移除的具体依赖情况;然而,有时可能面对的是间接传入的老化或不兼容版本问题。此时,除了简单地拒绝加载之外,还可以考虑主动替换为更新的选择。Gradle 自身具备自动选取最高版次的能力,不过也可以手动干预此过程以确保符合预期的行为模式[^2]。 另外一种场景是在跨项目编译过程中碰到重复且陈旧的基础构件引用。这时可在涉及跨项目的依赖声明处加入条件判断逻辑,针对性地屏蔽掉不需要的部分。比如下面的例子展示了怎样防止从公共工程继承下来的较低级别的七压缩绑定件影响到主程序集: ```groovy compile(project(':module-common')) { exclude(group: 'net.sf.sevenzipjbinding', module: 'sevenzipjbinding') } // 明确指出要用的新版本替代品 implementation 'net.sf.sevenzipjbinding:sevenzipjbinding:16.02-2.01' ``` 值得注意的是,以上措施均需谨慎施行以免误伤其他正常工作的功能单元。因此建议先充分理解整个系统的架构布局再做决定,并尽可能保留必要的日志记录以便后续追踪验证效果[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值