开发者社区 问答 正文

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



1. 问题


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

2. 问题原因


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

3. 解决方案


通过修改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文件即可,如:
  1. com/alibaba/sdk/android/push/securitybox/alipush/AliPushSecurityBoxService
  2. com/alibaba/sdk/android/push/CloudPushService
  3. ......

展开
收起
猫饭先生 2017-10-24 09:31:49 2522 分享 版权
阿里云 AI 助理回答

并且(it.name.endsWith('MainDexClassList') || it.name.endsWith('MainDexList'))}.each { task ->      task.doLast {          def output = task.outputs.files.singleFile          def input = file('multidex-config.txt')          if (input.exists()) {            def includeList = input.readLines().collect { 'class ' + it }            output.text = output.text + '\n' + includeList.join('\n')          }      }    }} 在上述解决方案中,首先通过afterEvaluate在Gradle构建过程的后期阶段执行操作,这样可以确保所有配置都已经解析完成。然后,使用tasks.matching来查找以create开头且以MainDexClassListMainDexList结尾的任务,这些任务通常负责生成主dex类列表。

接下来,对找到的每个任务执行一个doLast操作,这意味着在任务执行完成后会额外执行一些操作。这里读取一个名为multidex-config.txt的文件(您需要创建这个文件并列出需要包含到Main Dex中的类名),将这些类名添加到Main Dex的类列表中。

请确保multidex-config.txt文件位于您的项目根目录下,并且每一行包含一个需要被加入Main Dex的类的全限定名。例如:

com.aliyun.push.PushService
com.aliyun.push.example.MyApplication

这样,当您的应用构建时,指定的类就会被确保包含在主DEX文件中,从而避免了运行时因找不到类而抛出java.lang.NoClassDefFoundError的错误。记得在修改完Gradle脚本后同步项目并重新构建App。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答