分析您的 Gradle 依赖项
塞贡法米萨--2024 年 3 月 14 日
作为 Android 开发人员,我们有时可能需要调查或分析我们正在使用的 Gradle 依赖项。无论我们是试图找出我们正在使用的库的版本,还是试图找出一个可能不寻常的依赖项来自哪里,我们最终都可能需要这些知识。
一个短篇故事。最近,我们发现LeakCanary(我们用来检测内存泄漏)在我们的项目中被停用。经过调查,我发现它已被停用,因为测试依赖项被意外添加到我们的调试版本的类路径中。因此,我必须调查以找出存在哪些测试依赖项以及它是如何到达那里的。
在这篇文章中,我将分享一些技巧,帮助您分析 Gradle 依赖项并进行调试。
分析配置
首先,要分析依赖关系,需要知道正在寻找哪种依赖关系。我们可以通过尝试了解依赖项的声明方式来做到这一点- 这决定了它们如何最终出现在类路径中。换句话说,我们需要了解配置。
配置是告诉 Gradle 如何准确打包这些依赖项以实现最终输出的一种方式。有些依赖项可能仅在编译时使用,而有些依赖项在编译时和运行时都需要。有些甚至可能具有特殊行为,或与kapt
和之类的插件有关系ksp
,或者仅在某些源集中可用 - 例如测试。
正如Google 声明依赖项指南中所述,一些官方支持的配置包括、api
、implementation
等。compileOnly``runtimeOnly
在 7.5 及更高版本中,Gradle 提供了ResolvableConfigurationsTask任务,用于报告项目中可以解析的所有配置。任务按如下所示运行。
ruby
./gradlew :app:resolvableConfigurations
app
这里可以替换为您感兴趣的 Gradle 模块。
报告被打印到命令行,因此,我经常喜欢将命令的输出通过管道传输到文件,以便我可以正确打开和搜索。您可以通过运行来做到这一点./gradlew :app:resolvableConfigurations > conf.txt
。
该报告打印所有配置,包括它们的名称、属性以及它们扩展的其他配置。其中一种配置 ( debugCompileClasspath
) 如下所示:
ini
--------------------------------------------------
Configuration debugCompileClasspath
--------------------------------------------------
Compile classpath for compilation 'debug' (target (androidJvm)).
Attributes
- com.android.build.api.attributes.AgpVersionAttr = 7.4.2
- com.android.build.api.attributes.BuildTypeAttr = debug
- org.gradle.jvm.environment = android
- org.gradle.usage = java-api
- org.jetbrains.kotlin.platform.type = androidJvm
Extended Configurations
- compileOnly
- debugCompileOnly
- debugImplementation
- implementation
...
如果您试图找出应用程序编译了哪些依赖项,则编译类路径通常是您感兴趣的内容 - 因此您可以检查每种构建类型和产品风味组合的编译类路径。
好的。现在,我们已经确定了要研究的配置。让我们继续检查该配置中哪些依赖项可用。
分析依赖关系
为了分析依赖关系,我们可以使用两个任务。和dependency
任务dependencyInsights
。
该dependency
任务采用一个参数--configuration
,告诉 Gradle 您对哪个配置的依赖项感兴趣。运行的示例如下:
ruby
./gradlew :app:dependencies --configuration debugCompileClasspath
上面的命令打印出debugCompileClasspath
配置中应用的所有依赖项 - 即打包到调试版本中的所有依赖项。该命令的输出如下所示:
lua
------------------------------------------------------------
Project ':android:app'
------------------------------------------------------------
debugCompileClasspath - Compile classpath for compilation 'debug' (target (androidJvm)).
...
+--- org.jetbrains.kotlin:kotlin-stdlib:1.7.20 (*)
+--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 (*)
+--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4 (*)
+--- io.arrow-kt:arrow-core:0.8.1
| +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.0 -> 1.7.10 (*)
| --- io.arrow-kt:arrow-annotations:0.8.1
| +--- org.jetbrains.kotlin:kotlin-stdlib:1.3.0 -> 1.7.20 (*)
| --- io.kindedj:kindedj:1.1.0
+--- androidx.compose:compose-bom:2022.12.00
...
另一方面,如果我们已经知道要查找哪个依赖项,则可以使用该dependencyInsight
任务并指定依赖项名称group:name
或部分依赖项名称。例如,要查找有关上面的 arrow-kt 依赖项的信息,我们可以运行:
bash
./gradlew -q app:dependencyInsight --configuration debugCompileClasspath --dependency arrow-kt
结论
事实证明,上述方法对于调试和分析项目中的依赖关系非常有帮助。我可以确定项目中存在哪些配置,并利用该信息,我可以探索该配置中的依赖项。
通过这些命令,我能够查明哪个依赖项导致我们的 LeakCanary 被停用并提供修复。
我想还有其他用例,例如调查传递依赖项,或者在版本冲突的情况下,找出如何解决冲突以及哪个版本取代另一个版本,仅举几例。
感谢您的阅读。我希望这在某种程度上有帮助或提供信息。
有关 Gradle 依赖项的更多信息,您可以查看以下资源: