APK编译错误之Duplicate class

为了快速开发,不免使用些第三方库,这时,第三方库的依赖包与我们原来引用的同名包就可能存在版本冲突。这里,记录一个在Android Studio 3.4.1中引用了某第三方库后,编译时出现Duplicate class的问题及其解决办法。编译输出如下图:

Build Output

意思是,相同的类出现在了两个不同版本的com.android.support包里。同时,查看build.gradle时发现有如下图提示:

Gradle Notice

这里的意思是我们要引用相同版本的com.android.support包。回想出现问题前做过什么,也就是添加了一个第三方库com.vincent.filepicker:MultiTypeFilePicker:1.0.8来选择文件,考虑到项目原来用到的com.android.support 是28.0版本,那么日志中提到的com.android.support 26.1版本,就是这个第三方库所引用的版本了。找到问题所在后,接下来考虑解决办法,有两种思路:一是让项目使用第三方库引用的com.android.support版本;一种是第三方库使用原项目引用的com.android.support版本。

使用第三方库引用的com.android.support版本

使用这种方法,只要在build.gradle中,把以下三项的版本修改为第三方库引用的版本即可:

1
2
3
compileSdkVersion 28
targetSdkVersion 28
implementation 'com.android.support:appcompat-v7:28.0.0'

修改为

1
2
3
compileSdkVersion 26
targetSdkVersion 26
implementation 'com.android.support:appcompat-v7:26.1.0'

修改完成之后,在此案例中即可成功编译并使用。但如果我们需要使用com.android.support高版本的一些特性,这种方法可能就不能用了,因此,我们可以考虑使用下一种方法。

使用原项目引用的com.android.support版本

这里,用到implementation配置项的一个特性exclude,来排除传递依赖项。在这个例子里,仅需把

1
implementation 'com.vincent.filepicker:MultiTypeFilePicker:1.0.8'

修改为

1
2
3
implementation('com.vincent.filepicker:MultiTypeFilePicker:1.0.8') {
exclude group: 'com.android.support'
}

即可排除com.vincent.filepicker:MultiTypeFilePicker:1.0.8所指定的com.android.support版本,这样,项目中使用com.android.support接口的地方,包括com.vincent.filepicker:MultiTypeFilePicker:1.0.8,只会链接到28版本。然而,如果第三方库用到了的某些接口,在我们指定的版本上已不再可用时,这种方法就不能用了。当然,这种情况很少见,如果出现,那说明这个库也该被淘汰了。

参考

Android Studio User Guide——Add build dependencies节中关于排除依赖的描述