集成Android SDK后运行App报java.lang.NoClassDefFoundError该如何解决?

问题详述

接入移动推送 SDK 后,运行时报出java.lang.NoClassDefFoundError找不到某个类,但SDK中明明包含这个类,为什么会这样?

问题原因

如果您的App工程使用了multidex架构,可能会出现java.lang.NoClassDefFoundError,原因在于:推送SDK由于需要在application中进行初始化,所以相关类需要被放到MainDex文件中,否则在app启动时可能会报错。

解决方法

通过修改Gradle构建脚本,可以将一些类显示放到MainDex中:

  1. afterEvaluate {
  2. tasks.matching{
  3. it.name.startsWith('create') && it.name.endsWith('MainDexClassList')
  4. }.each { tk ->
  5. tk.doLast {
  6. keepMainMultiDex(tk.outputFile);
  7. }
  8. }
  9. }
  10. /**
  11. * 控制MainDex中的class列表
  12. * 将multidex.keep的内容追加到 maindexlist.txt 中
  13. * @param outputFile
  14. */
  15. def keepMainMultiDex(File outputFile){
  16. File keepFile = file("multidex.keep");
  17. outputFile << '\n'
  18. outputFile << keepFile.getText('UTF-8')
  19. }

这样在gradle的构建过程中,会将multidex.keep文件中的类同样打到maindex中。接下来只需要将报出NoClassDefFoundError的类写到multidex.keep文件即可(在app根目录下创建),如:

  1. com/alibaba/sdk/android/push/securitybox/alipush/AliPushSecurityBoxService
  2. com/alibaba/sdk/android/push/CloudPushService
  3. ......

该问题为常规开发问题,MultiDex的使用建议直接看官方API文档,此处示例如未生效,也可以在网上搜索”Multidex分包:将指定的类打包到主dex中”,配置后可以自行反编译查看是否将找不到的类已打进主dex。