Gradle: compileOnly and runtimeOnly

22
I can definitely help you with that! Here's the translated text:

我已经阅读了文档,但是我不知道如何创建一个工作示例来更好地理解它们之间的区别。

enter image description here

当然,我已经创建了一个游乐项目来检查使用其中一个会发生什么。

app.gradle

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$rootProject.kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.core:core-ktx:1.2.0'
    compileOnly project(":compileonlylibrary")
    runtimeOnly project(":runtimeonlylibrary")
}

MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        FooCompile() // this crash in runtime
        BarRuntime() // this doesn't compiles obviously
    }
}
// FooCompile belongs to compileonlylibrary
// BarRuntime belongs to runtimeonlylibrary

就是这样,我卡在这里了,我无法创建一个适当的示例来提高我的Gradle配置知识。

有人可以帮帮我吗?如果需要,我可以提供更多细节。

2个回答

15
  • 实现:大多数情况下我们使用实现配置。它隐藏了模块对其使用者的内部依赖关系,以避免意外使用任何传递依赖项,从而提高编译速度并减少重新编译。

  • api:必须非常小心地使用,因为它会泄漏给消费者的编译类路径,因此滥用api可能会导致依赖项污染。

  • compileOnly:当我们不需要在运行时使用任何依赖项时使用,因为compileOnly依赖项不会成为最终构建的一部分。我们将获得较小的构建大小。

  • runtimeOnly:当我们想要在运行时更改或交换库的行为(在最终构建中)时使用。

我创建了一篇帖子,深入理解每个内容,并附有工作示例:源代码

https://medium.com/@gauraw.negi/how-gradle-dependency-configurations-work-underhood-e934906752e5


11

compileOnly依赖项在编译时可用,但在运行时不可用。

这相当于Maven中provided作用域。

这意味着每个想要执行它的人都需要提供一个包含CompileOnly库中所有类的库。

例如,您可以创建一个使用SLF4J API的库,并将其设置为CompileOnly

任何使用该库的人都需要(显式地)导入某个版本的SLF4J API才能使用它。

runtimeOnly库则相反,在编译时不可用,但在运行时可用。

例如,您不需要在编译时使用具体的SLF4J日志记录器(例如logback),因为您使用SLF4J类来访问它,但是您在运行时需要它以便使用它。

让我们看下面的例子:

您有一个使用SLF4J的库:

compileOnly org.slf4j:slf4j-api:1.7.30

而且您可以使用该库来开展项目:

implementation project(":yourlibrary")
implementation org.slf4j:slf4j-api:2.0.0-alpha1
runtimeOnly ch.qos.logback:logback:0.5

SLF4J可以在运行时检测到具体的记录器,无需在编译时知道日志库(如logback)。这就是为仅使用runtimeOnly记录器的原因。


请注意,compileOnly广泛用于Jakarta EE,因为许多依赖项由JEE容器/应用程序服务器提供,如OP发现的博客中所示。


1
我理解这些差异,但我的问题是我不知道如何将这些知识应用于我的利益。这就是为什么我想要一个项目示例或类似的东西。 - Ricardo
好的,我找到了一篇非常棒的文章 https://blog.gradle.org/introducing-compile-only-dependencies 关于 compileOnly 的用例,现在我正在寻找 runtimeOnly。 - Ricardo
我不是很擅长安卓,但是https://dev59.com/SVYN5IYBdhLWcg3wfYK9#47365147表明`runtimeOnly`就像`apk`。 - dan1st
1
@dan1st “SLF4J在运行时检测具体的日志记录器,它不需要在运行时了解日志库(如logback)”你是否想在结尾处写“在编译时”而不是“在运行时”? - kolistivra
1
是的,我的错,谢谢您的纠正。 - dan1st
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接