关于gradle的implementation、api和compileOnly三种依赖方式
implementation: 参与编译和打包,依赖的包不对其它工程开放api : 参与编译和打包,依赖的包对其它工程开放compileOnly: 参与编译但不参与打包,依赖的包对其它工程不开放。如果整个工程紧使用comileOnly方式依赖某个包,在使用时编译不报错,但运行的时候会找不到该类。如果有其它moudle使用了implementation或者api 方式依赖,那么运行时就不会报错,最终
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占位依赖的方式正好满足这一需求
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)