Android 库:当 "implementation project" 用于库的模块依赖时找不到 Class 文件
Android library: Class file not found when "implementation project" is used for module dependency of a library
我在一个包含 3 个模块的项目中工作,如下所示:
Project
|
|-- Common
|
|-- SDK
|
|-- App
Common
是所有其他模块都依赖的 Android 库模块,但我不必在任何地方发布它,因为它只包含其他模块的公共代码。另一方面,SDK
是另一个 Android 库项目,必须在我们的内部工件上发布。
App
是SDK的示例工程。我能够毫无问题地发布 SDK
工件,但是当我将其导入客户端应用程序时,编译失败,因为 Common
模块中 classes 的 none找到了。
对于 SDK 模块所依赖的第三方依赖项,我使用 implementation
(例如 implementation 'com.squareup.okhttp3:okhttp:3.11.0'
,并且所有这些依赖项都已成功添加到 SDK
POM 文件中),对于我使用 implementation project(path: ':Common')
.
对 Common
模块的依赖
在导入 SDK
库的客户端应用程序中,编译器显示以下错误
Error: cannot access Foo
class file for com.acme.Foo not found
(Foo是Common模块中的一个class)
为什么当我从 Common
模块中导入 class 的 SDK
none 时?我期望编译器将这两个模块合并为一个模块。有没有人知道我如何解决这个问题?
(我知道一个解决方案是在 artifactory 上发布 Common
但我不想这样做,因为这只是内部通用代码)。
将 implementation project(path: ':Common')
替换为 api project(path: ':Common')
关于 api 和实现之间的区别,您可以查看 this article.
这是 gradle 模块的预期行为;如您所料,将每个发布为单独的工件(并在 pom 文件中列出依赖项)是唯一受支持的用法。
https://github.com/adwiv/android-fat-aar 上有一个插件可以满足您的需要,但它不再维护,因此您的使用情况可能会有所不同。
或者,您可以通过更新 SDK 源集以直接指向公共模块源并完全删除 gradle 依赖项来获得类似的结果。找不到好的 link ,但应该可以。这确实删除了模块的所有内置处理,但可能会更好地匹配您使用模块的方式。
我自己也有类似的问题。
视觉帮助是使用Android Studio
它自己的项目结构视图:
File -> Project Structure
那么对于你的 :app
你可以检查你有什么 modules dependencies
:
如果需要,您可以删除当前模块依赖项并再次添加它们以进行仔细检查。之后当您单击 "OK" gradle 时将尝试同步其文件。
这样您就可以让 Android Studio 完成集成所有模块的工作,希望它能解决您的问题。
PS: 我相信您导入项目的方式有误。您应该使用 api
而不是 implementation
。来自文档:
api: When a module includes an api dependency, it's letting Gradle
know that the module wants to transitively export that dependency to
other modules, so that it's available to them at both runtime and
compile time. This configuration behaves just like compile (which is
now deprecated), and you should typically use this only in library
modules. That's because, if an api dependency changes its external
API, Gradle recompiles all modules that have access to that dependency
at compile time. So, having a large number of api dependencies can
significantly increase build times. Unless you want to expose a
dependency's API to a separate test module, app modules should instead
use implementation dependencies.
查看官方文档:https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html#new_configurations
我遇到过同样的问题。
就我而言,我创建了一个 kotlin
库并尝试添加 java 项目。所以请确保 kotlin
应该为库配置。
现在对我有用。
André Sousa 得票最多的答案是正确的,但只有在您不直接使用库中的任何依赖项时它才有用。
常见的情况是您有一个 'Common' 模块,它可能会导入一些常用库(Joda DateTime、firebase 等)。在这种情况下,库中的所有此类依赖项都需要使用 'api' 而不是 'implementation' 来声明。这确保当您的应用程序导入您的 Common 模块时,这些 类 也可用。
我在一个包含 3 个模块的项目中工作,如下所示:
Project
|
|-- Common
|
|-- SDK
|
|-- App
Common
是所有其他模块都依赖的 Android 库模块,但我不必在任何地方发布它,因为它只包含其他模块的公共代码。另一方面,SDK
是另一个 Android 库项目,必须在我们的内部工件上发布。
App
是SDK的示例工程。我能够毫无问题地发布 SDK
工件,但是当我将其导入客户端应用程序时,编译失败,因为 Common
模块中 classes 的 none找到了。
对于 SDK 模块所依赖的第三方依赖项,我使用 implementation
(例如 implementation 'com.squareup.okhttp3:okhttp:3.11.0'
,并且所有这些依赖项都已成功添加到 SDK
POM 文件中),对于我使用 implementation project(path: ':Common')
.
Common
模块的依赖
在导入 SDK
库的客户端应用程序中,编译器显示以下错误
Error: cannot access Foo
class file for com.acme.Foo not found
(Foo是Common模块中的一个class)
为什么当我从 Common
模块中导入 class 的 SDK
none 时?我期望编译器将这两个模块合并为一个模块。有没有人知道我如何解决这个问题?
(我知道一个解决方案是在 artifactory 上发布 Common
但我不想这样做,因为这只是内部通用代码)。
将 implementation project(path: ':Common')
替换为 api project(path: ':Common')
关于 api 和实现之间的区别,您可以查看 this article.
这是 gradle 模块的预期行为;如您所料,将每个发布为单独的工件(并在 pom 文件中列出依赖项)是唯一受支持的用法。
https://github.com/adwiv/android-fat-aar 上有一个插件可以满足您的需要,但它不再维护,因此您的使用情况可能会有所不同。 或者,您可以通过更新 SDK 源集以直接指向公共模块源并完全删除 gradle 依赖项来获得类似的结果。找不到好的 link ,但应该可以。这确实删除了模块的所有内置处理,但可能会更好地匹配您使用模块的方式。
我自己也有类似的问题。
视觉帮助是使用Android Studio
它自己的项目结构视图:
File -> Project Structure
那么对于你的 :app
你可以检查你有什么 modules dependencies
:
如果需要,您可以删除当前模块依赖项并再次添加它们以进行仔细检查。之后当您单击 "OK" gradle 时将尝试同步其文件。
这样您就可以让 Android Studio 完成集成所有模块的工作,希望它能解决您的问题。
PS: 我相信您导入项目的方式有误。您应该使用 api
而不是 implementation
。来自文档:
api: When a module includes an api dependency, it's letting Gradle know that the module wants to transitively export that dependency to other modules, so that it's available to them at both runtime and compile time. This configuration behaves just like compile (which is now deprecated), and you should typically use this only in library modules. That's because, if an api dependency changes its external API, Gradle recompiles all modules that have access to that dependency at compile time. So, having a large number of api dependencies can significantly increase build times. Unless you want to expose a dependency's API to a separate test module, app modules should instead use implementation dependencies.
查看官方文档:https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html#new_configurations
我遇到过同样的问题。
就我而言,我创建了一个 kotlin
库并尝试添加 java 项目。所以请确保 kotlin
应该为库配置。
现在对我有用。
André Sousa 得票最多的答案是正确的,但只有在您不直接使用库中的任何依赖项时它才有用。
常见的情况是您有一个 'Common' 模块,它可能会导入一些常用库(Joda DateTime、firebase 等)。在这种情况下,库中的所有此类依赖项都需要使用 'api' 而不是 'implementation' 来声明。这确保当您的应用程序导入您的 Common 模块时,这些 类 也可用。