Gradle:compileOnly 和 runtimeOnly

Ric*_*rdo 9 android gradle

我已经阅读了文档,但我无法理解如何创建一个工作示例以更好地理解它们的差异。

在此处输入图片说明

而且我已经创建了一个游乐场项目来检查当我使用一个或另一个时会发生什么。

应用程序.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")
}
Run Code Online (Sandbox Code Playgroud)

主活动.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
Run Code Online (Sandbox Code Playgroud)

就是这样,我被困在这里,我无法创建一个合适的示例来提高我对 Gradle 配置的了解。

有人可以帮我一把吗?如果需要,我可以提供更多详细信息。

Gau*_*egi 18

    \n
  • 执行:我们主要使用实现配置。它隐藏了模块对其使用者的内部依赖关系,以避免意外使用任何传递依赖关系,从而加快编译速度并减少重新编译。

    \n
  • \n
  • 应用程序编程接口:必须非常小心地使用,因为它会泄漏到consumer\xe2\x80\x99s编译类路径,因此滥用api可能会导致依赖污染。

    \n
  • \n
  • 仅编译:当我们在运行时不需要任何依赖项时,因为compileOnly依赖项不会成为最终构建的一部分。我们将得到更小的构建尺寸。

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

    \n
  • \n
\n

我创建了一篇文章,对每一个都有深入的了解,通过工作示例:源代码

\n

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

\n


dan*_*1st 5

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

这相当于providedmaven 中的作用域。

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

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

使用该库的任何人都需要(明确)导入某些版本的 SLF4J API 才能使用它。

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

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

让我们看看下面的例子:

您有一个使用 SLF4J 的库:

compileOnly org.slf4j:slf4j-api:1.7.30
Run Code Online (Sandbox Code Playgroud)

你可以有一个使用库的项目:

implementation project(":yourlibrary")
implementation org.slf4j:slf4j-api:2.0.0-alpha1
runtimeOnly ch.qos.logback:logback:0.5
Run Code Online (Sandbox Code Playgroud)

SLF4J 在运行时检测具体的记录器,它不需要在编译时知道日志库(如 logback)。这就是您可以runtimeOnly用于具体记录器的原因。


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