Android库:将“实现项目”用于库的模块依赖项时找不到类文件

时间:2018-10-20 10:35:03

标签: android gradle android-gradle dependencies android-library

我正在一个有3个模块的项目中工作,如下所示:

Project
|
|-- Common 
|
|-- SDK
|
|-- App

Common是一个其他所有模块都依赖的Android库模块,但是我不必在任何地方发布它,因为它仅包含其他模块的通用代码。另一方面,SDK是另一个Android库项目,必须在我们的内部工件上发布。

App是SDK的示例项目。我可以毫无问题地发布SDK工件,但是当我将其导入客户端应用程序时,编译失败,因为找不到Common模块中的任何类。

对于SDK模块所依赖的第三方依赖项,我使用implementation(例如implementation 'com.squareup.okhttp3:okhttp:3.11.0',并且所有那些依赖项都已成功添加到SDK POM文件中),并且依赖于我使用Common的{​​{1}}模块。

在导入implementation project(path: ':Common')库的客户端应用程序中,编译器显示以下错误

SDK

(Foo是“通用”模块中的类)

为什么当我导入Error: cannot access Foo class file for com.acme.Foo not found 模块时,找不到SDK模块中的所有类?我期望的是编译器将两个模块合并为一个模块。有谁知道我该如何解决这个问题?

(我知道一种解决方案是在工件上发布Common,但我不想这样做,因为这只是内部通用代码)。

6 个答案:

答案 0 :(得分:3)

implementation project(path: ':Common')补充api project(path: ':Common') 关于api和实现之间的区别,您可以检查this article

答案 1 :(得分:1)

这是gradle模块的预期行为;如您所料,唯一支持的用法是将它们作为单独的工件发布(并在pom文件中列出依赖项)。

https://github.com/adwiv/android-fat-aar中有一个插件可以满足您的需要,但是不再维护,因此您的行程可能会有所不同。 另外,您可以通过更新SDK的SourceSet使其直接指向通用模块源,并完全删除gradle依赖项来获得类似的结果。为此找不到很好的链接,但是应该可以的。这确实删除了模块的所有内置处理,但可能会更好地匹配您使用模块的方式。

答案 2 :(得分:1)

我自己也遇到过类似的问题。

视觉帮助是使用Android Studio自己的项目结构视图:enter image description here

  

文件->项目结构

然后为您的:app检查您拥有的modules dependencies

enter image description here

如果需要,可以删除当前模块依赖项,然后再次添加它们,以进行仔细检查。之后,当您单击“确定”时,gradle将尝试同步其文件。

通过这种方式,您可以让Android Studio完成集成所有模块的工作,并希望它将解决您的问题。


PS::我认为您导入的项目是错误的方式。您应该使用api而不是implementation。从文档中:

  

api::当模块包含api依赖项时,它将让Gradle   知道该模块希望将该依赖关系可传递到   其他模块,以便在运行时和   编译时间。此配置的行为就像编译(   现在已弃用),通常只应在库中使用此功能   模块。这是因为,如果api依赖项更改了其外部   API,Gradle重新编译所有可以访问该依赖项的模块   在编译时。因此,拥有大量的api依赖项可以   大大增加了构建时间。除非您想公开   依赖项的API到单独的测试模块,应用模块应改为   使用实现依赖。

检查官方文档:https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html#new_configurations

答案 3 :(得分:0)

我也遇到过同样的问题。

就我而言,我创建了一个kotlin库,并尝试使用Java项目添加。因此,请确保应为库配置kotlin

现在对我有用。

答案 4 :(得分:0)

安德烈·索萨(AndréSousa)投票最多的答案是正确的,但这仅在您不直接使用库中的任何依赖项时才有帮助。

常见的情况是您有一个“通用”模块,该模块可能会导入一些通用库(Joda DateTime,firebase等)。在这种情况下,库中的所有此类依赖项都需要使用“ api”声明,而不是“实现”。这样可以确保当您的应用程序导入Common模块时,这些类也可用。

答案 5 :(得分:-1)

因为SDK是客户端所在的库,所以支持@Aolphn用implementation project(path: ':SDK')替换api project(path: ':SDK')