65536 问题/解决方案

Android 开发中,经典的 65536 问题不少人应该都碰到过,也就是这个:

Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536

对于这个问题的原因,这里我借用这篇文章的一段话概括下,感谢文章作者的总结。

这个错误是 Android 应用的方法总数限制造成的。Android 平台的 Java 虚拟机 Dalvik 在执行 DEX 格式的 Java 应用程序时,使用原生类型 short 来索引 DEX 文件中的方法。这意味着单个 DEX 文件可被引用的方法总数被限制为 65536。通常 APK 包含一个 classes.dex 文件,因此 Android 应用的方法总数不能超过这个数量,这包括 Android 框架、类库和你自己开发的代码。

原因了解了,如何解决,这里我简单汇总一些方案:

Google 官方的 MultiDex 方案

Configure Apps with Over 64K Methods

美团的多 Dex 分包、动态异步加载方案

美团Android DEX自动拆包及动态加载简介

插件化,动态加载方案

其它

Hack Dalvik VM 解决 Android 2.3 DEX/LinearAllocHdr 超限

一些经验

要预防 65536 问题,其实可以理解为就是如何尽可能的控制目标 method 数。

关于第三方库的选择(尽量用小而美的工具包来辅助开发)

  • JSON 类库的选择,在 Jackson, Gson, Fastjson 中,综合来说,Gson 比较均衡,method 总数在 1k 左右;
  • 不建议使用 Guava 这个工具包,method 总数在 1w 以上,可以考虑用 Apache 的 commons 相关工具包代替,另外,Jodd 也是不错的选择;
  • 如果 App 有用到 Google Protobuf,那么推荐用 Square 的 Wire;
  • 相同功能的第三方库,选择其中一个合适的即可,如上面说的 JSON 相关的,还有图片加载、网络库等;
  • 如果可以,尝试用合适的方式抽取一些类库中需要的那部分代码来辅助开发;
  • dex-method-counts 是个好工具,还有 http://www.methodscount.com

总之,慎用第三方库。

另外,再推荐一篇文章,預防 Android Dex 64k Method Size Limit

题外话

当遇到问题时,我习惯这样来思考:

  • 问题出现的原因是什么?
    • 低级错误,粗心大意造成?
    • 对某些原理(API)不了解?
    • 确实是某(些)疑难杂症?
  • 如何解决?
    • Review, Review, Review
    • 查文档,找相关资料
    • 善用 Google 找解决方案(大部分问题都是有靠谱的方案的)

概括来说就是:

发现问题 - 分析问题 - 解决问题 - 总结经验(教训)

参考资料