我写了一个 Android 库,封装了公司上一些常用的控件,其中该库也引用了其他第三方的控件。
姑且把这个库称为Library A,然后引用了一个第三方库Gson,我想在工程Project1中引用Library A,以便提高效率。
现在我把Library A打包成一个 AAR ,然后复制到工程Project1中,然后调用Library A里面的方法。编译没有问题,但是一运行,就会报一个 ClassNotFoundException的错误,表示找不到第三方库Gson 。
但是如果我在Project1中加多一句compile 'com.google.code.gson:gson:2.8.0
就不会崩溃了。
最开始我以为是没把Gson打包到Library A中,解包Library A的 AAR 也是没有发现Gson的 jar 。所以一开始走了弯路,想办法把Gson的 jar 打包到Library A。在网上找到一个android-fat-aar的脚本,说是可以把第三方库也打包到 AAR 中。但是,打包完却又总是报Multiple dex files define的错误。
最后在 stackoverflow 上看到一个回答,说不应该把第三方的库打包进 AAR ,这些依赖应该由 maven 来处理。
接下来就根据这个教程搭建了一个私有的 maven 仓库,并且把Library A上传到私有仓库中。
并且在Project1中用compile 'com.example:LibraryA:1.0.0'
这种形式成功引用到Library A。但是一运行还是继续报ClassNotFoundException的错误。
接着找到资料,说是要通过 pom.xml 来传递依赖。然后在找到一个build.gradle
示例,是这样写的:
忽略无关的语句
def libraryGroupId = 'com.example' def libraryArtifactId = 'LibraryA' def libraryVersion = '1.0.0' publishing { publications { aar(MavenPublication) { groupId libraryGroupId version libraryVersion artifactId libraryArtifactId artifact("$buildDir/outputs/aar/${artifactId}-release.aar") //generate POM file pom.withXml { def root = asNode() def dependenciesNode = root.appendNode('dependencies') //Iterate over the compile dependencies (we don't want the test ones), adding a <dependency> node for each configurations.compile.allDependencies.each { if (it.group != null) { def dependencyNode = dependenciesNode.appendNode('dependency') dependencyNode.appendNode('groupId', it.group) dependencyNode.appendNode('artifactId', it.name) dependencyNode.appendNode('version', it.version) dependencyNode.appendNode('scope','compile') } } } } } } artifactory { contextUrl = 'http://localserver:8081/artifactory' publish { repository { repoKey = 'libs-release-local' username = artifactory_username password = artifactory_password } defaults { publications('aar') publishArtifacts = true properties = ['qa.level': 'basic', 'q.os': 'android', 'dev.team': 'core'] publishPom = true } } }
执行后在私有的 maven 仓库上,的确看到如下的 dependency
<dependency> <groupId>com.android.volley</groupId> <artifactId>volley</artifactId> <version>1.0.0</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.0</version> <scope>compile</scope> </dependency> ......省略其他依赖
但是一调用又崩溃了,又提示找不到类。
然后我看了一下Project1的依赖,发现只引用了Library A,并没有引用Library A的依赖。
com.exmaple:Library:1.0.0并没有像com.android.support:appcompat-v7:25.2.0一样列出所需的依赖。
折腾了好几天愣是没搞明白 maven 的依赖到底要怎么写。故请教一下各位,有没有朋友遇到过这样的问题?
我想要实现的效果,就是可以在新的项目中直接compile 'com.example:LibraryA:1.0.0
就可以引用我自己的库,而不用再去声明Library A所需要的依赖
谢谢:)
1
kaneg 2017-03-11 14:04:50 +08:00 via iPhone
你的新 project 没有写 pom ?
|
2
tongpeng1995 OP @kaneg 没呀,新 Project 为什么要写 pom ? pom 不是库才需要写的么?
|
3
ArthurKing 2017-03-11 15:32:48 +08:00
maven 项目不写 pom 文件?是我 out 了?
|
4
tongpeng1995 OP @ArthurKing 求指点,我对 maven 并不熟悉😂,刚接触不久,一直没搞明白如何声明依赖。
|
5
nonesuccess 2017-03-11 18:09:35 +08:00 via Android
@tongpeng1995 找个 maven 入门教程看看吧,至少先知道为什么 pom 文件是必须的再说
|
6
kaneg 2017-03-11 19:35:27 +08:00 via iPhone
@tongpeng1995 这就是你的新项目找不到 class 的原因,要把新项目都纳入 maven 的体系,依赖传递的特性才能起作用
|
7
jackleeforce3615 2019-03-14 15:17:58 +08:00
在 Project 1 中的 build.gradle 里面使用 transitive = true,如
compile ('com.example:LibraryA:1.0.0 ){ transitive = true } 或者 compile(group: 'com.example', name: 'LibraryA', version: '1.0.0', ext: 'aar') { transitive = true } |