【Android studio】【Gradle】dependencies配置参数细解及异常解决
依赖项配置
implementation
Gradle 会将依赖项添加到编译类路径,并将依赖项打包到构建输出。不过,当您的模块配置 implementation 依赖项时,会让 Gradle 了解您不希望该模块在编译时将该依赖项泄露给其他模块。也就是说,其他模块只有在运行时才能使用该依赖项。
使用此依赖项配置代替 api 或 compile(已弃用)可以显著缩短构建时间,因为这样可以减少构建系统需要重新编译的模块数。例如,如果 implementation 依赖项更改了其 API,Gradle 只会重新编译该依赖项以及直接依赖于它的模块。大多数应用和测试模块都应使用此配置。
api
Gradle 会将依赖项添加到编译类路径和构建输出。当一个模块包含 api 依赖项时,会让 Gradle 了解该模块要以传递方式将该依赖项导出到其他模块,以便这些模块在运行时和编译时都可以使用该依赖项。
此配置的行为类似于 compile(现已弃用),但使用它时应格外小心,只能对您需要以传递方式导出到其他上游消费者的依赖项使用它。这是因为,如果 api 依赖项更改了其外部 API,Gradle 会在编译时重新编译所有有权访问该依赖项的模块。因此,拥有大量的 api 依赖项会显著增加构建时间。除非要将依赖项的 API 公开给单独的模块,否则库模块应改用 implementation 依赖项。
compileOnly
Gradle 只会将依赖项添加到编译类路径(也就是说,不会将其添加到构建输出)。如果您创建 Android 模块时在编译期间需要相应依赖项,但它在运行时可有可无,此配置会很有用。
如果您使用此配置,那么您的库模块必须包含一个运行时条件,用于检查是否提供了相应依赖项,然后适当地改变该模块的行为,以使该模块在未提供相应依赖项的情况下仍可正常运行。这样做不会添加不重要的瞬时依赖项,因而有助于减小最终 APK 的大小。此配置的行为类似于 provided(现已弃用)。
注意:您不能将 compileOnly 配置与 AAR 依赖项配合使用。
runtimeOnly
Gradle 只会将依赖项添加到构建输出,以便在运行时使用。也就是说,不会将其添加到编译类路径。此配置的行为类似于 apk(现已弃用)。
annotationProcessor
如需添加对作为注解处理器的库的依赖,您必须使用 annotationProcessor 配置将其添加到注解处理器的类路径。这是因为,使用此配置可以将编译类路径与注释处理器类路径分开,从而提高构建性能。如果 Gradle 在编译类路径上找到注释处理器,则会禁用避免编译功能,这样会对构建时间产生负面影响(Gradle 5.0 及更高版本会忽略在编译类路径上找到的注释处理器)。
如果 JAR 文件包含以下文件,则 Android Gradle 插件会假定依赖项是注释处理器:
META-INF/services/javax.annotation.processing.Processor。 如果插件检测到编译类路径上包含注解处理器,则会产生构建错误。
注意:Kotlin 项目应使用 kapt 声明注解处理器依赖项。
lintChecks
使用此配置可以添加您希望 Gradle 在构建项目时执行的 lint 检查。
注意:使用 Android Gradle 插件 3.4.0 及更高版本时,此依赖项配置不再将 lint 检查打包在 Android 库项目中。如需将 lint 检查依赖项包含在 AAR 库中,请使用下面介绍的 lintPublish 配置。
lintPublish
在 Android 库项目中使用此配置可以添加您希望 Gradle 编译成 lint.jar 文件并打包在 AAR 中的 lint 检查。这会使得使用 AAR 的项目也应用这些 lint 检查。如果您之前使用 lintChecks 依赖项配置将 lint 检查添加到已发布的 AAR 中,则需要迁移这些依赖项以改用 lintPublish 配置。
dependencies {
// Executes lint checks from the ':checks' project
// at build time.
lintChecks project(':checks')
// Compiles lint checks from the ':checks-to-publish'
// into a lint.jar file and publishes it to your
// Android library.
lintPublish project(':checks-to-publish')
}
已弃用的配置(在 AGP 1.0–4.2 中可用)
apk
Gradle 只会将依赖项添加到构建输出,以便在运行时使用。也就是说,不会将其添加到编译类路径。
compile
Gradle 会将依赖项添加到编译类路径和构建输出。 将依赖项导出到其他模块。
provided
Gradle 只会将依赖项添加到编译类路径(也就是说,不会将其添加到构建输出)。
异常情况
Error: Annotation processors must be explicitly declared now.
如需解决此错误,请使用 annotationProcessor 配置依赖项,以将注解处理器添加到您的项目,如下所示:
dependencies {
// Adds libraries defining annotations to only the compile classpath.
compileOnly 'com.google.dagger:dagger:version-number'
// Adds the annotation processor dependency to the annotation processor classpath.
annotationProcessor 'com.google.dagger:dagger-compiler:version-number'
}
Error:Failed to resolve: Could not resolve project :mylibrary.Required by:project :app
使用变体感知型依赖项管理机制
Error:Failed to resolve: Could not resolve project :mylibrary.
Required by:
project :app
您的应用包含库依赖项不包含的构建类型。
例如,您的应用包含“staging”版本类型,但依赖项仅包含“debug”和“release”版本类型。
请注意,如果库依赖项包含您的应用不包含的编译类型,这不会引发问题。这是因为,插件在任何时候都不会从依赖项请求该构建类型。
使用 matchingFallbacks 为给定的构建类型指定替代匹配,如下所示:
// In the app's build.gradle file.
android {
buildTypes {
debug {}
release {}
staging {
// Specifies a sorted list of fallback build types that the
// plugin should try to use when a dependency does not include a
// "staging" build type. You may specify as many fallbacks as you
// like, and the plugin selects the first build type that's
// available in the dependency.
matchingFallbacks = ['debug', 'qa', 'release']
}
}
}
对于应用及其库依赖项中均存在的给定变种维度,您的应用包含库不包含的变种。
例如,您的应用及其库依赖项都包含“tier”变种维度。不过,应用中的“tier”维度包含“free”和“paid”变种,但依赖项中的同一维度仅包含“demo”和“paid”变种。
请注意,对于应用及其库依赖项中均存在的给定变种维度,如果库包含您的应用不包含的产品变种,这不会引发问题。这是因为,插件在任何时候都不会从依赖项请求该变种。
使用 matchingFallbacks 为应用的“free”产品变种指定替代匹配,如下所示:
// In the app's build.gradle file.
android {
defaultConfig{
// Do not configure matchingFallbacks in the defaultConfig block.
// Instead, you must specify fallbacks for a given product flavor in the
// productFlavors block, as shown below.
}
flavorDimensions 'tier'
productFlavors {
paid {
dimension 'tier'
// Because the dependency already includes a "paid" flavor in its
// "tier" dimension, you don't need to provide a list of fallbacks
// for the "paid" flavor.
}
free {
dimension 'tier'
// Specifies a sorted list of fallback flavors that the plugin
// should try to use when a dependency's matching dimension does
// not include a "free" flavor. You may specify as many
// fallbacks as you like, and the plugin selects the first flavor
// that's available in the dependency's "tier" dimension.
matchingFallbacks = ['demo', 'trial']
}
}
}
库依赖项包含您的应用不包含的变种维度。
例如,库依赖项包含“minApi”维度的变种,但您的应用仅包含“tier”维度的变种。因此,当您要构建“freeDebug”版本的应用时,插件不知道是使用“minApi23Debug”还是“minApi18Debug”版本的依赖项。
请注意,如果您的应用包含库依赖项不包含的变种维度,这不会引发问题。这是因为,插件只会匹配依赖项中存在的维度的变种。例如,如果依赖项不包含 ABI 的维度,“freeX86Debug”版本的应用将直接使用“freeDebug”版本的依赖项。
在 defaultConfig 代码块中使用 missingDimensionStrategy 指定插件应从每个缺失维度中选择的默认变种,如以下示例所示。您也可以替换在 productFlavors 代码块中的选择,让每一个变种都可以为缺失维度指定一个不同的匹配策略。
// In the app's build.gradle file.
android {
defaultConfig{
// Specifies a sorted list of flavors that the plugin should try to use from
// a given dimension. The following tells the plugin that, when encountering
// a dependency that includes a "minApi" dimension, it should select the
// "minApi18" flavor. You can include additional flavor names to provide a
// sorted list of fallbacks for the dimension.
missingDimensionStrategy 'minApi', 'minApi18', 'minApi23'
// You should specify a missingDimensionStrategy property for each
// dimension that exists in a local dependency but not in your app.
missingDimensionStrategy 'abi', 'x86', 'arm64'
}
flavorDimensions 'tier'
productFlavors {
free {
dimension 'tier'
// You can override the default selection at the product flavor
// level by configuring another missingDimensionStrategy property
// for the "minApi" dimension.
missingDimensionStrategy 'minApi', 'minApi23', 'minApi18'
}
paid {}
}
}
修复重复类错误
如果某个类多次出现在运行时类路径上,您会收到一条与以下内容类似的错误:
Program type already present com.example.MyClass
此错误通常是下列其中一种情况所致:
二进制文件依赖项包含一个库,该库也作为直接依赖项包含在您的应用中。例如,您的应用声明直接依赖于库 A 和库 B,但库 A 已在其二进制文件中包含库 B。
如需解决此问题,请取消将库 B 作为直接依赖项。
您的应用的本地二进制文件依赖项和远程二进制文件依赖项是同一个库。
如需解决此问题,请移除其中一个二进制文件依赖项。
解决类路径之间的冲突
Conflict with dependency 'com.example.library:some-lib:2.0' in project 'my-library'.
Resolved versions for runtime classpath (1.0) and compile classpath (2.0) differ.
如需解决此问题,请执行以下某项操作:
将所需版本的依赖项作为 api 依赖项添加到库模块。也就是说,尽管只有库模块声明了相应依赖项,但应用模块同样能够访问其 API。
或者,您也可以同时在两个模块中声明相应依赖项,但应确保两个模块使用的依赖项版本相同。不妨考虑配置项目全局属性,以确保每个依赖项的版本在整个项目中保持一致。
Error:All flavors must now belong to a named flavor dimension.The flavor ‘flavor_name’ is not assigned to a flavor dimension.
所有变种都必须属于一个指定的变种维度,即一个产品变种组。您必须将所有变种分配给某个变种维度;否则,您将收到如上所示的构建错误。如果给定的模块仅指定一个变种维度,那么 Android Gradle 插件会自动将该模块的所有变种分配给该维度。
自研产品推荐
历时一年半多开发终于smartApi-v1.0.0版本在2023-09-15晚十点正式上线
smartApi是一款对标国外的postman的api调试开发工具,由于开发人力就作者一个所以人力有限,因此v1.0.0版本功能进行精简,大功能项有:
- api参数填写
- api请求响应数据展示
- PDF形式的分享文档
- Mock本地化解决方案
- api列表数据本地化处理
- 再加上UI方面的打磨
为了更好服务大家把之前的公众号和软件激活结合,如有疑问请大家反馈到公众号即可,下个版本30%以上的更新会来自公众号的反馈。
嗯!先解释不上服务端原因,API调试工具的绝大多数时候就是一个数据模型、数据处理、数据模型理解共识的问题解决工具,所以作者结合自己十多年开发使用的一些痛点来打造的,再加上服务端开发一般是面向企业的,作者目前没有精力和时间去打造企业服务。再加上没有资金投入所以服务端开发会滞后,至于什么时候会进行开发,这个要看募资情况和用户反馈综合考虑。虽然目前国内有些比较知名的api工具了,但作者使用后还是觉得和实际使用场景不符。如果有相关吐槽也可以在作者的公众号里反馈蛤!
下面是一段smartApi使用介绍: