10 月 23 - 25 日,QCon 上海站即将召开,现在购票,享9折优惠 了解详情
写点什么

Android 应用打破 65K 方法数限制

  • 2014-11-09
  • 本文字数:2069 字

    阅读完需:约 7 分钟

近日, Android Developers 在 Google+ 上宣布了新的Multidex 支持库,为方法总数超过65K 的Android 应用提供了官方支持。

如果你是一名幸运的Android 应用开发者,正在开发一个前景广阔的应用,不断地加入新功能、添加新的类库,那么终有一天,你会不幸遇到这个错误:

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 框架、类库和你自己开发的代码。

这个问题可以通过将一个 DEX 文件分拆成多个 DEX 文件解决。Facebook 介绍了为 Android 应用开发的 Dalvik 补丁;Android Developers 博客介绍了通过自定义类加载过程的方法来解决此问题。但这些方法有些复杂而且并不优雅。

随着新的MultiDex 支持库发布,Google 正式为解决此问题提供官方支持。构建超过65K 方法数的应用介绍了如何使用Gradle 构建多DEX 应用。

首先使用Android SDK Manager 升级到最新的Android SDK Build Tools 和Android Support Library R21。然后进行以下两步操作:

1. 修改 Gradle 配置文件,启用 MultiDex 并包含 MultiDex 支持:

复制代码
android { compileSdkVersion 21 buildToolsVersion "21.1.0"
defaultConfig {
...
minSdkVersion 14
targetSdkVersion 21
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
dependencies { compile 'com.android.support:multidex:1.0.0' }

2. 让应用支持多 DEX 文件。在 MultiDexApplication JavaDoc 中描述了三种可选方法:

  • 在 AndroidManifest.xml 的 application 中声明 android.support.multidex.MultiDexApplication;
  • 如果你已经有自己的 Application 类,让其继承 MultiDexApplication;
  • 如果你的 Application 类已经继承自其它类,你不想 / 能修改它,那么可以重写 attachBaseContext() 方法:
复制代码
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base); MultiDex.install(this);
}

经过以上步骤,你的应用已经可以实现多个 DEX 文件了。当应用构建时,构建工具会分析哪些类必须放在第一个 DEX 文件,哪些类可以放在附加的 DEX 文件中。当它创建了第一个 DEX 文件(classes.dex)后,如果有必要会继续创建附加的 DEX 文件,如 classes2.dex, classes3.dex。Multidex 的支持类库将被包含在应用的第一个 DEX 文件中,帮助实现对其它 DEX 文件的访问。

文中还介绍了在开发多 DEX 应用时,通过设置 productFlavors 提高开发效率以及多 DEX 应用的测试方法。

Android 5.0 和更高版本使用名为 ART 的运行时,它原生支持从 APK 文件加载多个 DEX 文件。在应用安装时,它会执行预编译,扫描 classes(…N).dex 文件然后将其编译成单个.oat 文件用于执行。了解更多关于 ART 的信息

虽然 Google 解决了应用总方法数限制的问题,但并不意味着开发者可以任意扩大项目规模。Multidex 仍有一些限制:

  1. DEX 文件安装到设备的过程非常复杂,如果第二个 DEX 文件太大,可能导致应用无响应。此时应该使用 ProGuard 减小 DEX 文件的大小。
  2. 由于 Dalvik linearAlloc 的 Bug ,应用可能无法在 Android 4.0 之前的版本启动,如果你的应用要支持这些版本就要多执行测试。
  3. 同样因为 Dalvik linearAlloc 的限制,如果请求大量内存可能导致崩溃。Dalvik linearAlloc 是一个固定大小的缓冲区。在应用的安装过程中,系统会运行一个名为 dexopt 的程序为该应用在当前机型中运行做准备。dexopt 使用 LinearAlloc 来存储应用的方法信息。Android 2.2 和 2.3 的缓冲区只有 5MB,Android 4.x 提高到了 8MB 或 16MB。当方法数量过多导致超出缓冲区大小时,会造成 dexopt 崩溃。
  4. Multidex 构建工具还不支持指定哪些类必须包含在首个 DEX 文件中,因此可能会导致某些类库(例如某个类库需要从原生代码访问 Java 代码)无法使用。

避免应用过大、方法过多仍然是 Android 开发者要注意的问题。Mihai Parparita 的开源项目 dex-method-counts 可以用于统计 APK 中每个包的方法数量。

通常开发者自己的代码很难达到这样的方法数量限制,但随着第三方类库的加入,方法数就会迅速膨胀。因此选择合适的类库对 Android 开发者来说尤为重要。

开发者应该避免使用 Google Guava 这样的类库,它包含了 13000 多个方法。尽量使用专为移动应用设计的 Lite/Android 版本类库,或者使用小类库替换大类库,例如用 Google-gson 替换 Jackson JSON。而对于 Google Protocol Buffers 这样的数据交换格式,其标准实现会自动生成大量的方法。采用 Square Wire 的实现则可以很好地解决此问题。

给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2014-11-09 09:4528386

评论

发布
暂无评论
发现更多内容

阿里P9架构师推荐的Spring领域巅峰之作,颠覆了我对Spring的认知

程序知音

Java spring java架构 Java进阶 后端技术

点云分割技术的发展现状及挑战

数据堂

塞尔达工业革命卷到数字电路了!网友:怕不是要在Switch里造Switch

Openlab_cosmoplat

Sprint回顾会及Scrum工具

顿顿顿

Scrum 敏捷开发 敏捷项目管理 敏捷开发管理工具 sprint回顾会

软件测试|pyecharts绘制NBA球星得分能力对比图

霍格沃兹测试开发学社

Scrum的执行过程及产品Backlog梳理的目的、时间、内容

顿顿顿

Scrum 敏捷开发 敏捷开发管理 敏捷项目管理

SSH和SFTP是否相同

镭速

我国首例汽车企业全业务场景数据出境安全评估获批

Openlab_cosmoplat

大数据 开源 汽车

低代码开发:构建企业数字化生态系统的秘密武器!

加入高科技仿生人

低代码 数字化 企业数字化 数字转型

激发创造力!如何轻松录制PPT和人像视频

淋雨

PPT Camtasia 录屏

上海国家会计学院杨寅: 数据、业务、技术三大事项相互融合,促进财务发展

用友BIP

智能会计 价值财务

我的 UI 组件库发布了!

DUFU

JavaScript Svelte 移动端 Tailwind UI组件库

【活动报名】openEuler如何实现高效运维?南京用户组Meetup现场来聊聊!

openEuler

Linux 运维 操作系统 openEuler

2023上海国际嵌入式展 | 如何通过版本控制与IP管理建立嵌入式开发的单一可信数据源

龙智—DevSecOps解决方案

版本控制 嵌入式开发 静态代码扫描

分布式架构天花板笔记开源了,一上线GitHub 45K star

小小怪下士

Java 程序员 分布式 分布式架构

伟大的公司只需要十一人

Openlab_cosmoplat

开源 MidJourney

面试进阶齐飞!Github一天10w赞的阿里Java系统性能优化笔记有多牛?

程序员小毕

JVM 面试题 架构师 java面试 Java性能优化

软件测试/测试开发丨自动化测试定位策略实战-测试人论坛搜索

测试人

程序员 软件测试 自动化测试 测试开发

开发者们:618电商团战即将开启,“抢流量”想上分,必备这三个大招 | MobTech观察

MobTech袤博科技

软件测试|码农必会的git操作(一)

霍格沃兹测试开发学社

缺乏集成和标准的协作框架,企业如何确保API质量?

龙智—DevSecOps解决方案

git API API 接口

数学计算软件开发巨头MathWorks助力嵌入式开发创新,将MATLAB、Simulink与Perforce Helix Core集成

龙智—DevSecOps解决方案

版本控制 数学计算软件 MathWorks

如何在Windows中设置应用程序开机启动?

IT蜗壳-Tango

Kyligence 客户案例招商银行批发业务分析平台获评金融数字化最佳实践案例

Kyligence

金融数字化 指标平台

flutter系列之:做一个下载按钮的动画

程序那些事

flutter 大前端 程序那些事

基于低代码平台的多租户解决方案

力软低代码开发平台

能让中国联通青睐的财务共享智能报账平台是什么样的?

用友BIP

财务共享

异地组网——ZeroTier

数新网络官方账号

大数据

浅谈安全测试之AppScan

数新网络官方账号

大数据 安全测试

腾讯广告技术版图|把脉生意困局,助力全域经营

科技热闻

MobTech 秒验|运营商网关取号​

MobTech袤博科技

Android应用打破65K方法数限制_Android/iOS_梅雪松_InfoQ精选文章