我有一个Android项目,其中Glide v4是其依赖项之一。
该项目还有另一个依赖项,我们称之为dependency A
,它依赖于Glide v3。
我不知道这是否重要,但是dependency A
只能作为aar加入。
所以这是我的build.gradle
的一部分:
implementation(name: 'dependency_a', ext: 'aar')
implementation ("com.github.bumptech.glide:glide:4.7.1") {
exclude group: "com.android.support"
}
annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
该应用可以编译;但是当运行dependency A
中的代码使用Glide v3时:
Glide.with(context).load(imageUrl).asBitmap().into(new SimpleTarget<Bitmap>() {...}
应用程序崩溃并显示以下消息:
java.lang.NoSuchMethodError: No virtual method load(Ljava/lang/String;)Lcom/bumptech/glide/DrawableTypeRequest; in class Lcom/bumptech/glide/RequestManager; or its super classes (declaration of 'com.bumptech.glide.RequestManager' appears in /data/app/{my.package.name}}-LItMzBkBqXw3lyYYdKp-SA==/base.apk:classes15.dex)
我正在寻找一种在dependency A
中保留Glide v3的方法,但仍将Glide v4用于我的应用程序和其他依赖项。
有可能吗?
这是因为另一个dependency B
需要我使用Glide v4。
答案 0 :(得分:4)
Gradle的依赖关系解决方案是在有多个替代方案可用或需要多种替代方案时选择一个一个版本。
在给定的ClassLoader中,对于给定的类全名,最终只能有一个Class,所以可能性是:
更改程序包名称。例如,海绵堡从org.bouncycastle.*
移至org.spongycastle.*
以避免与平台版本冲突。
使用多个类加载器。我相信Android支持custom class loader,但这可能会涉及很多工作,并且存在一些隐患。
不幸的是,我认为这都不是您所需要的实际解决方案。
答案 1 :(得分:2)
我猜您别无选择,只能使用更新的 Glide v4 ,因为您已经说过,您也在使用 Glide v4 。另外,如果您使用更新的依赖项/库,那会很好,因为新版本中应用了性能改进和错误修复。
答案 2 :(得分:2)
Gradle通过选择here中提到的模块的最高版本来解决版本冲突。因此,如果您使用v3和v4作为依赖关系,则将使用v4。
由于Glide从v3到v4进行了重大更改,因此您将崩溃,依赖项A无法使用v4的方法。
解决方案1 -依赖项B必须使用v3以避免冲突。依赖项A升级到v4后,升级到v4。
解决方案2 -如果依赖项A可以在没有Glide依赖项的情况下正常运行,则可以将Glide从依赖项A中排除。
答案 3 :(得分:2)
可以将您的应用拆分为多个二进制文件吗?可以将一个二进制文件与依赖项A和Glade 3关联,而将另一个二进制文件与依赖项B和Glade 4关联吗?
仅当可以清楚地区分依赖于A和Glade 3的应用程序部分以及依赖于B和Glade 4的应用程序部分,以便每个二进制文件可以这种方法在概念上类似于object oriented design或Unix philosophy组合单一用途工具以促进复杂的工作流程的方法或COM架构在Windows上。
在评估这种拆分是否可行时,您将需要考虑用户工作流程和数据存储以及特定于应用程序的特征。例如,如果用户将顺序从二进制A移到二进制B,并且二进制A是启动序列的一部分,并且用户从不返回二进制A,则表明拆分是可能的。另一方面,如果用户在二进制文件A和二进制文件B之间来回跳动,则拆分变得更加困难。同样,如果数据存储在数据库中,并且每个二进制文件都可以独立访问数据,则拆分可能是可行的。相反,如果数据主要存储在流程中,和/或在流程之间有大量数据要流传输,则拆分可能不可行。
以这种方式使用多个二进制文件时,他们可能需要使用某种API进行通信,例如,命令行,管道,文件套接字,网络套接字,甚至只是两个二进制文件都可以访问的共享外部数据存储异步。
通常,限制二进制文件之间的交互作用越多,效果越好。您也许可以围绕依赖项A和Glade 3创建一个简单的包装器,然后从其余代码中调用该包装器。
最后,如果您评估并发现将应用程序拆分为多个二进制文件是可行的,那么在继续之前,请考虑将应用程序拆分相对于为A和B指定新依赖项的相对努力。