关于gradle的implementation、api和compileOnly三种依赖方式

  • implementation: 参与编译和打包,依赖的包不对其它工程开放
  • api : 参与编译和打包,依赖的包对其它工程开放
  • compileOnly: 参与编译但不参与打包,依赖的包对其它工程不开放。如果整个工程紧使用comileOnly方式依赖某个包,在使用时编译不报错,但运行的时候会找不到该类。如果有其它moudle使用了implementation或者api 方式依赖,那么运行时就不会报错,最终依赖的是其它module所导入的包

一 场景主工程app依赖于moduleB,moduleB依赖于Gson包,在app当中调用Gson的方法

app:

implementation project(path: ':B')

方式一:B使用implementation依赖:

 implementation 'com.google.code.gson:gson:2.6.2'

效果:在工程A中调用Gson方法会编译不通过

在这里插入图片描述

  • 结论:implementation不对外提供依赖的包,参与编译打包

方式二:B使用api依赖:

 api 'com.google.code.gson:gson:2.6.2'

效果:app中调用Gson方法正常编译并且运行

在这里插入图片描述

  • 结论:api对外提供工程所依赖的包,并且参与编译和打包

方式三:B使用compileOnly依赖:

compileOnly 'com.google.code.gson:gson:2.6.2'
  • 结论:如方式一一样编译不通过,说明工程B依赖的Gson不对外开放,compileOnly不对外提供依赖的包

二 场景app使用compileOnly方式依赖Gson,注:此时工程A没有依赖B

app:

compileOnly 'com.google.code.gson:gson:2.6.2'

在工程A当中使用Gson

在这里插入图片描述

编译正常通过,打包运行找不类:

在这里插入图片描述

  • 结论:compileOnly参与编译不参与打包

问题一:app依赖于B并使用compileOnly依赖Gson包,同时B中使用implementation依赖Gson包,在app当中使用Gson,那么效果怎样?

效果:正常编译和运行

app使用了compileOnly方式依赖了Gson包,Gson参与了编译,所以app当中使用Gson能够正常编译

那么为何能够正常运行呢?

B当中使用implementation方式依赖了Gson,虽然在编译时不提供对外依赖给app,但打包时将Gson打包到了apk中,所以app运行时可以找到Gson包,故运行不报错

思考,compileOnly存在的意义?

我们在使用第三方包的时候经常面临包冲突的问题,如果我们提供包给别人用,如何来避免使用人员的包冲突问题呢?

同样以Gson包为例,如果我们指定了我们module的Gson包版本为2.6.1使用如下两种方式依赖

//    implementation 'com.google.code.gson:gson:2.6.1'
//        api 'com.google.code.gson:gson:2.6.1'

那么使用我们module开发人员,也依赖了一个 Gson包,版本为2.6.2

//    implementation 'com.google.code.gson:gson:2.6.2'
//        api 'com.google.code.gson:gson:2.6.2'

这样一来就打包运行时,apk当中就存在了两个gson包,不但使apk体积增大,还可能造成app运行报错

如何避免?

如果我们有一种方式,在我们写自己的moudle时能够正常调用Gson包但不指定版本,具体版本由使用者来指定,这样就能避免最终app当中Gson版本不同的问题,compileOnly占位依赖的方式正好满足这一需求

  • 14
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
gradle implementationcompile都是在项目中使用的依赖管理关键字。 在旧版本的Gradle中,使用的是compile关键字来引入项目中所需要的依赖库。例如,使用compile 'com.android.support:appcompat-v7:28.0.0'来引入Android Support库中的appcompat库。 然而,在Gradle 3.0及以上的版本中,compile已经被implementation所取代。这是由于implementation可以更好地处理依赖的传递性问题。所谓的传递性问题是指当一个库依赖另外一个库时,是否需要将被依赖的库也自动地引入到项目中。 通过使用implementation关键字,Gradle能够更好地优化编译过程,只将直接使用的库引入项目中,而不会将间接使用的库也引入项目中。这可以有效减少项目的编译时间,并减少最终应用包的大小。 例如,假设库A依赖库B,而项目只直接使用了库A。如果使用compile关键字,则会将库B也引入到项目中,即使项目中并没有直接使用库B。但如果使用implementation关键字,则只会将库A引入项目中,不会引入库B,从而减少了项目的依赖。 除了implementation之外,还有另外两个依赖管理关键字:api和testImplementationapi关键字可以将依赖库引入到项目的编译路径中,并可以传递给依赖项目。而testImplementation关键字则是专门用于引入测试时所需的库。 总而言之,compile和implementation都是用于项目中的依赖管理,但Gradle 3.0及以上的版本推荐使用implementation来更好地管理项目的依赖关系。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值