Library Publication 是 Gradle 在0.9.0 时增加的一个新特性,它的作用是让Lib也能发布不同的版本
在这之前,Lib只能发布release版本,你的项目中依赖的所有Lib也都只能是relaese版本的。这种做法看起来很合理,被依赖的库当然应该是release的,debug状态下怎么给其他项目提供依赖呀?但在实际多模块项目中,被依赖的库只是项目中普普通通的一部分,库和项目同时被开发被调试,debug状态的Lib也是非常正常的,于是很早就有人给Google提了一个issue: ,Google工程师便在gradle的0.9.0版本中增加了Library Publication特性来处理这个问题,不过好像直到1.0才完全处理好
(转载请注明:博客园-阁刚广志,地址:http://www.cnblogs.com/bellkosmos/p/6437171.html )
对我来说,我写的很多工具包都会打印Log,而工具包自然会放在通用的模块里,所以我当然希望Log能根据模块当前的buildtype来决定是否打印,于是我对这个common lib 使用了Library Publication这个特性
Library Publication 不会改变之前的构建过程,只是在gradle脚本中增加了一些配置,就实现了Lib的多版本发布
Google工程师的实现思路非常简单:
- 还是只需要选择application的variant就可以直接打包
- 改动在于,让 [application依赖的library的variant] 被 [application的variant] 控制
你具体的使用方式是也非常简洁:
- 在library中设置让library发布自己的全部variant:android.publishNonDefault = true
- 然后在application中的reference中标明不同的 [application的variant] 依赖的不同的 [library具体的variant] :debugCompile project(path: ':Library', configuration: 'debug')
更细的说明文档: 可以看这里
但我在实际项目中使用时,发现直接就同步不过去,报错信息是“more than one library with package name:XXX”
正常情况下,Gradle会处理好重复依赖的问题,但是这里居然会报这个错误,那一定是我们在Library Publication时出了问题
原来还是因为我的项目中依赖关系有些乱,造成了一个复杂的构建情况,导致了构建问题,这个问题的原理说起来非常简单:
- 假设有这样一个多模块项目:
-
- 应用A依赖库B和库C,同时库B和库C又都依赖库D
- 在库D上使用了新特性发布全版本,然后在库C上使用新特性控制:当C是debug的时候D也是debug、C是release的时候D也是release
- 同时在C上也发布全版本,A通过新特性控制C的版本就像C控制D一样
- 而A对B不做控制,B对D也不做控制
- 这时,但是如果你进行debug构建,就会出现问题
- 因为当应用A是debug的时候,库C是被新特性控制成debug的了,同样D也是debug,另一边库B只默认构建release版本,就自然使用了release,而库B依赖的库D因为是普通依赖,自然也是默认的release
- 这样整个项目中就会存在一个debug的库D和一个release的库D,Gradle就报了构建错误:more than one library with package name:XXX
- (如果你对应用A进行release构建,不会有问题,可以自己推理一下原因)
知道原因之后解决这个问题就可以直接对症下药了:让库B也发布全版本,让项目A控制库B的版本,让库B控制库D的版本