Gradle 中的transitive = true 究竟做了啥(w.r.t. crashlytics)?

Posted

技术标签:

【中文标题】Gradle 中的transitive = true 究竟做了啥(w.r.t. crashlytics)?【英文标题】:What does transitive = true in Gradle exactly do (w.r.t. crashlytics)?Gradle 中的transitive = true 究竟做了什么(w.r.t. crashlytics)? 【发布时间】:2015-10-22 05:42:59 【问题描述】:

Gradle transitive = true 究竟做了什么?从Gradle documentation 不清楚。这是在build.gradle 内的compile 的上下文中。就我而言,我依赖于 android 的 crashlytics。

compile('com.crashlytics.sdk.android:crashlytics:2.2.2@aar') 
    transitive = true;

几个 Gradle 文档(here 和 here)暗示“传递”默认为 true。然而删除transitive = true 会导致传递依赖没有被引入(尤其是KitGroup)。

class file for io.fabric.sdk.android.KitGroup not found

文档说它默认为 true,但实际行为似乎相反。

我正在运行 Gradle 2.2.1。也许行为在 2.2 和 2.4 之间发生了变化?

编辑:相关Transitive dependencies not resolved for aar library using gradle

【问题讨论】:

什么时候定义配置,或者什么时候定义依赖关系? jar 文件的依赖被提升到子项目。不是每个项目都需要明确定义它的依赖关系。 this documentation 中究竟有什么不清楚的地方? @OlegEstekhin 文档与我看到的运行时行为不匹配 【参考方案1】:

transitive 控制传递性。 Gradle 通常默认为可传递的,除非它不是。传递性和分类器存在错误,请参阅https://issues.gradle.org/browse/GRADLE-3188。

【讨论】:

我认为你指出了一个错误是公平的。但是,您对房产的描述没有帮助。 “传递性控制传递性。Gradle 通常默认为传递性,除非它不是。”真的吗,伙计?...真的吗? @w3bshark 我觉得这很有趣。根据我的经验,“默认为传递,除非它不是传递”是非常准确的。 @w3bshark 我不太关心选票。我正在与社区分享我学到的东西。【参考方案2】:

我的猜测是,您所引用的 Crashlytics 工件手动将依赖项指定为 not 可传递的 (transitive=false),这样您就不必在默认情况下引入这些依赖项。这就是为什么您会看到相反的行为。例如,一些开发人员可能不想引入所有 Google Play 服务或 Crashlytics 可能使用的任何其他服务(如果存在)。

因此,通过删除它,Gradle 不再引入依赖项,并且无法构建。如果需要,您可以手动指定该依赖项。

话虽如此 - 我认为手头的更大问题是您不应该直接引用 Crashlytics 工件 - 您应该使用 Fabric,并因此引入 Crashlytics:@987654321 @

【讨论】:

迁移到 Fabric 的说明指定直接引用 Crashlytics 工件,假设您正在使用该 Fabric“工具包”:fabric.io/migrations/gradle 看起来意图是您直接引用工具包,它们通过传递依赖引入 io.fabric.sdk.android 类。【参考方案3】:

您正在使用@aar 表示法。 这意味着您只想下载 aar 工件,而不是传递依赖项。

你可以在 Gradle 中查看依赖管理 在官方documentation。特别是:

仅工件表示法创建一个模块依赖项,它仅下载具有指定扩展名的工件文件。 忽略现有的模块描述符

如果要下载依赖项,请使用@aar 表示法,您应该添加 transitive=true

我希望省略 @aar 它应该可以在不添加传递属性的情况下工作。

【讨论】:

我确认省略 @aar 并删除传递属性有效。这里的意图是开发人员明确引用 Fabric 工具包(例如,“compile 'com.crashlytics.sdk.android:crashlytics:2.5.5'”),并且核心 io.fabric.sdk.android 类通过传递依赖。如果设置transitive=false,那么编译时将找不到io.fabric.sdk.android.Fabric 类。 这个“功能”太糟糕了,我想要一个带有依赖关系的 aar。没有@aar,它会搜索 jar 并抱怨 那有什么意义呢?为什么不避免一起使用“@aar”和“transitive=true”?【参考方案4】:

设置是否应解析此依赖项,包括或排除其传递依赖项。属于此依赖项的工件本身可能依赖于其他工件。后者称为传递依赖。

【讨论】:

【参考方案5】:

Gradle 默认遵循传递依赖。如果您想为特定库关闭它,请使用传递标志。

将传递标志的值更改为 false 会阻止下载传递依赖项,因此您必须自己添加所需的任何内容。 如果你只想要一个模块 jar,没有任何额外的依赖项,你也可以指定它。

【讨论】:

除了高度赞成的答案中的建议之外,这增加了什么价值? 那么如果默认开启,为什么各种SDK-tutorials都说要添加为true呢?【参考方案6】:

更一般的说明: 在 crashlytics 库上设置 transitive = false 会导致 gradle 忽略 crashlytics (="transient libraries") 所需的所有库,而不是下载和链接它们。

您必须手动将所需的库添加到您的项目中,或者依赖其他依赖项添加的其他临时库。

gradle 的默认值为transitive = true

示例和完整说明:http://www.devsbedevin.net/android-understanding-gradle-dependencies-and-resolving-conflicts/

【讨论】:

链接无效。恐怕默认不是true,因为在某些情况下特意写成true

以上是关于Gradle 中的transitive = true 究竟做了啥(w.r.t. crashlytics)?的主要内容,如果未能解决你的问题,请参考以下文章

Gradle-5.3:依赖-管理依赖的版本(传递(transitive)排除(exclude)强制(force)动态版本(+))

Android Gradle 插件Android 依赖管理 ⑥ ( 依赖冲突处理 | transitive 依赖传递设置 | exclude 依赖排除设置 | force 强制指定依赖库 )

gradle入门(1-4)gradle的依赖排除和强制引入

Gradle,如何禁用所有传递依赖

android gradle 强制版本

如何为本地.aar库设置transitive = true? [重复]