原文:https://developer.android.com/studio/build/multidex.html
随着Android平台不断增长,Android应用程序的规模也在不断增加。 当您的应用程序及其引用的库达到一定大小时,您会遇到构建错误,指出您的应用程序已达到Android应用程序构建体系结构的限制。 早期版本的构建系统报告此错误如下:

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

更多最新版本的Android构建系统显示不同的错误,这是同样问题的提示:

trouble writing output:
Too many field references: 131000; max is 65536.
You may try using --multi-dex option.

这两个错误情况都显示一个常用的数字:65,536。 这个数字很重要,因为它代表单个Dalvik Executable(dex)字节码文件中的代码可以调用的引用的总数。 如果你已经构建了一个Android应用程序并收到此错误,那么恭喜你,你有很多代码! 本文介绍如何超越此限制并继续构建您的应用程序。

注意:本文中提供的指南取代了Android开发人员博客中Dalvik中的自定义类加载中给出的指导。

关于64K引用限制


Android应用程序(APK)文件包含Dalvik可执行文件(DEX)形式的可执行字节码文件,它包含用于运行应用程序的编译代码。 Dalvik Executable规范将单个DEX文件中可以引用的方法的总数限制为65,536,包括Android框架方法,库方法和您自己的代码中的方法。 在计算机科学的上下文中,术语Kilo,K表示1024(或2 ^ 10)。 因为65,536等于64 X 1024,所以此限制称为“64K引用限制”。

超过此限制要求您配置您的应用程序构建过程以生成多个DEX文件,称为multidex配置。

在Android 5.0之前的Multidex支持

Android 5.0之前的平台版本(API级别21)使用Dalvik运行时执行应用程序代码。 默认情况下,Dalvik将应用程序限制为每个APK一个classes.dex字节码文件。 为了克服这个限制,您可以使用multidex支持库,它成为应用程序的主要DEX文件的一部分,然后管理对其他DEX文件及其包含的代码的访问。

注意:如果您的项目配置为使用minSdkVersion 20或更低版本的multidex,并且部署到运行Android 4.4(API级别20)或更低版本的目标设备,Android Studio将禁用即时运行。

在Android 5.0之后的Multidex支持

Android 5.0(API级别21)和更高版本使用一个运行时称为ART,ART本身支持从应用程序APK文件加载多个dex文件。 ART在应用程序安装时执行预编译,扫描类(.. N).dex文件,并将它们编译为单个.oat文件以供Android设备执行。 有关Android 5.0运行时的详细信息,请参阅ART简介。

注意:使用即时运行时,当您的应用程序的minSdkVersion设置为21或更高,Android Studio会自动将您的应用程序配置为multidex。 因为即时运行只适用于您的应用程序的调试版本,所以您仍然需要配置multidex的发布版本以避免64K限制。

避免64K限制


在配置应用以启用使用64K或更多方法引用之前,您应该采取措施减少应用代码调用的引用总数,包括由应用代码或包含的库定义的方法。 以下策略可帮助您避免达到dex参考限制:

  • 查看您应用程式的直接和间接依赖项-在应用程序中包含依赖关的任何大型库的代码量大于被使用的量。 一个常见的反模式是程序包含一个非常大的库,但只有一些的方法是有用的。 减少应用程式依赖项通常可以避免dex引用限制。
  • 使用ProGuard删除未使用的代码-为您的应用程序配置ProGuard设置以运行ProGuard,并确保已为发布版本启用缩减。 启用缩减功能可确保您不会使用APK传送未使用的代码。

使用Gradle配置Multidex应用程序


Android SDK中Gradle的Android插件Build Tools 21.1和更高版本支持multidex作为构建配置的一部分。 在尝试为multidex配置应用程序之前,请确保SDK Manager将Android SDK构建工具和Android支持存储库更新到最新版本。

将应用程序开发项目设置为使用multidex配置,需要对应用程序开发项目进行一些修改。 特别需要执行以下步骤:

  • 更改Gradle构建配置以启用multidex
  • 修改您的清单以引用MultiDexApplication

修改模块级build.gradle文件配置以包括支持库并启用multidex输出,如以下代码段所示:

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

在您的清单中将MultiDexApplication类从multidex支持库添加到应用程序元素。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.android.multidex.myapplication"><application...android:name="android.support.multidex.MultiDexApplication">...</application>
</manifest>

当这些配置设置添加到应用程序时,Android构建工具根据需要构造主要dex(classes.dex)和支持(classes2.dex,classes3.dex)。 构建系统然后将它们打包为APK文件以进行分发。

注意:如果应用程序使用扩展了Application类,则可以覆盖attachBaseContext()方法并调用MultiDex.install(this)以启用multidex。 有关详细信息,请参阅MultiDexApplication参考文档。

multidex支持库的局限性

multidex支持库有一些已知的限制,当合并到应用程序构建配置时应该注意和测试:

  • 在启动过程中将.dex文件安装到设备的数据分区上非常复杂,如果辅助dex文件较大,可能导致应用程序无响应(ANR)错误。 在这种情况下,您应该使用ProGuard应用代码缩减技术,以最小化dex文件的大小和删除未使用的代码部分。
  • 由于Dalvik linearAlloc错误(问题22586),使用multidex的应用程序可能无法在运行早于Android 4.0(API级别14)的平台的设备上启动。 如果您的目标API级别早于14,请确保使用这些版本的平台执行测试,因为您的应用程序在启动时或加载特定的类组时可能会出现问题。 代码缩减可以减少或可能消除这些潜在问题。
  • 由于Dalvik linearAlloc限制(问题78035),使用使用非常大内存分配请求的multidex配置的应用程序可能在运行时崩溃。 Android 4.0(API级别14)中的分配限制已增加,但在Android 5.0(API级别21)之前的Android版本中,应用仍可能达到此限制。
  • 对于在Dalvik运行时中执行时主要dex文件中需要什么类有复杂的要求。 Android构建工具更新处理Android需求,但是其他包含的库可能有额外的依赖性要求,包括使用自省或从本机代码调用Java方法。 在更新multidex构建工具之前,可能无法使用某些库,以允许您指定必须包含在主dex文件中的类。

优化Multidex开发构建


multidex配置要求大大增加构建处理时间,因为构建系统必须做出关于必须包括在主DEX文件中什么类以及哪些类可以包括在辅助DEX文件中的复杂决定。 这意味着使用multidex作为开发过程的一部分执行的常规构建通常需要更长时间,并且可能会减慢您的开发过程。

为了减少multidex输出的通常较长的构建时间,您应该使用Gradle productFlavors的Android插件在构建输出上创建两个变体:开发风格和生产风格。

对于开发风格,请设置最低SDK版本21.此设置使用ART支持的格式可以更快地生成multidex输出。 对于版本风格,请设置与实际最低支持级别匹配的最低SDK版本。 此设置会生成与更多设备兼容的multidex APK,但需要更长时间才能生成。

以下构建配置示例演示如何在Gradle构建文件中设置这些类型:

android {productFlavors {// Define separate dev and prod product flavors.dev {// dev utilizes minSDKVersion = 21 to allow the Android gradle plugin// to pre-dex each module and produce an APK that can be tested on// Android Lollipop without time consuming dex merging processes.minSdkVersion 21}prod {// The actual minSdkVersion for the application.minSdkVersion 14}}...buildTypes {release {runProguard trueproguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'}}
}
dependencies {compile 'com.android.support:multidex:1.0.0'
}

完成此配置更改后,您可以使用应用程序的devDebug变体,它结合了dev productFlavor和debug buildType的属性。 使用此目标创建一个调试应用程序,其中禁用proguard,启用multidex并将minSdkVersion设置为Android API级别21.这些设置使Android Gradle插件执行以下操作:

  1. 将应用程序的每个模块(包括依赖关系)构建为单独的dex文件。 这通常被称为预先dexing。
  2. 在APK中包含每个dex文件,而不进行修改。
  3. 最重要的是,模块dex文件不会被组合,因此避免了长期运行的计算,以确定主要dex文件的内容。

这些设置导致快速,增量构建,因为只有修改模块的dex文件被重新计算并重新打包到APK文件中。 从这些版本生成的APK只能用于在Android 5.0设备上测试。 但是,通过将配置实现为一个flavor,您可以保留使用适当的最低SDK级别和proguard设置执行正常构建的功能。

您还可以构建其他变体,包括prodDebug变体生成,它需要更长的构建,但可以用于在开发外测试。 在显示的配置中,prodRelease变体将是最终的测试和发布版本。 如果您从命令行执行gradle任务,则可以使用带有附加到其后的DevDebug的标准命令(例如./gradlew installDevDebug)。 有关使用Gradle任务使用flavor的更多信息,请参阅Gradle插件用户指南。

提示:您还可以为每个flavor提供自定义清单或自定义应用程序类,从而允许您使用支持库MultiDexApplication类,或仅对需要它的变体调用MultiDex.install()。

在Android Studio中使用构建变体

构建变量对于在使用multidex时管理构建过程非常有用。 Android Studio允许您在用户界面中选择这些构建版本。

要让Android Studio构建应用程序的“devDebug”变体:

  1. 从左侧栏中打开Build Variants 窗口。 选择Favorites
  2. 单击构建变量的名称以选择其他变体,如图1所示。

    图1. Android Studio左侧面板的屏幕截图,显示了构建版本。

注意:打开此窗口的选项仅在Tools > Android > Sync Project with Gradle Files命令成功同步Android Studio与Gradle构建文件后可用。

Multidex应用程序测试


为multidex应用程序编写测试测试时,不需要其他配置。 AndroidJUnitRunner支持multidex白盒测试,只要在自定义Application对象中使用MultiDexApplication或覆盖attachBaseContext()方法,并调用MultiDex.install(this)即可启用multidex。

或者,您可以覆盖AndroidJUnitRunner中的onCreate()方法:

public void onCreate(Bundle arguments) {MultiDex.install(getTargetContext());super.onCreate(arguments);...
}

注意:目前不支持使用multidex创建测试APK。

配置超过64K方法的应用程序相关推荐

  1. 方法超出 android,Android工程方法数超过64k,The number of method references in a .dex file cannot exceed 64K....

    最近将一个老的Eclipse项目转到Android Studio后,用gradle添加了几个依赖,项目可以make,但是一旦run就报错 Error:The number of method refe ...

  2. 解决richedit的内容不能超过64k的方法

    1.经试验和查阅,RichEdit控件输入文本内容的时候,的确不能超过64k(录入的内容不能超过64K,或者粘贴几百k的文本,就只显示64k的内容): 2.Memo控件不存在此问题,可以直接粘贴大量文 ...

  3. Sublime Text 3 配置和使用方法

    下载: Sublime Text 3 官方下载地址 Sublime Text 3 汉化破解版 资料: Sublime Text 非官方文档 技巧 -用户或-User后缀的菜单项,其对应的配置文件都保存 ...

  4. 4.3、Android Studio突破64K方法限制

    当应用代码和库代码代码超过64K限制时,早期版本的构建系统会出现如下提示: Conversion to Dalvik format failed: Unable to execute dex: met ...

  5. 中间件 BES 连接池的配置和问题诊断方法

    彭文元 云和恩墨技术专家 服务于某省移动公司BES中间件和数据库运维,在IT行业拥有10年以上的工作经历,包含产品开发.需求调研.数据库以及中间件的实施维护等.擅长 BES 中间件和 ORACLE 数 ...

  6. tomcat系列之编译超过64k大小的jsp文件报错原因

    今天遇到一个问题,首先是在tomcat中间件上跑的web项目,一个jsp文件,因为代码行数实在是太多了,更新了几个版本之后编译报错了,页面打开都是报500的错误,500的报错,知道http协议返回码的 ...

  7. Java8(jdk1.8)中文档注释处理工具javadoc的环境参量配置及使用方法

    Java8(jdk1.8)中文档注释处理工具javadoc的环境参量配置及使用方法 Java语言提供了一种功能强大的注释形式:文档注释.如果编写Java源代码时添加了合适的文档注释,然后通过JDK提供 ...

  8. c# 指定打开某个路径下的CMD_(win10下sublime通过配置JSON调用MATLAB直接运行程序)(转载)...

    SUBLIME作为文本编辑器,本身并不具备仿真功能.但通过配置JSON,可以调用任一程序. https://blog.csdn.net/solinger/article/details/8945016 ...

  9. Nginx的安装和多域名配置的实现方法

    这篇文章主要介绍了Nginx的安装和多域名配置的实现方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 Nginx安装 centos6.x yum默认没有nginx的软件 ...

最新文章

  1. 《麻省理工科技评论》:2018年18大科技趋势,2017年7大失败技术
  2. Python的matplotlib—绘图(3)
  3. 在知乎引发众多分布式数据库大佬争相回答的问题
  4. Redis(1) 简介以及linux环境下的安装
  5. Net分布式系统之:微服务架构
  6. 力扣 验证二叉搜索树
  7. Java:日期类Date与Calendar
  8. php curl jsonrpc,JsonRPC: Lightweight Json-RPC 2.0 client/server in PHP extension
  9. knn(k近邻算法)——python
  10. Code.V光学设计学习(一)——入门介绍
  11. word怎么删除不要的页,即刻删除空白页
  12. Android studio - UI 界面设计(仿问卷星登陆注册界面)
  13. 配置打印机共享时 报错 无法访问您可能没有权限使用网络资源
  14. Longhorn入门级教程!轻松实现持久化存储!
  15. 无法加载文件C:\Users\TANG\AppData\Roaming\npm\nrm.ps1,因为在此系统上禁止运行脚本
  16. 2.1.3 客户端网络连接对象
  17. ARTIX-7 XC7A35T实验项目之 串口发送
  18. 一次迭代式开发的研究:一个迭代式项目计划
  19. 不忍舍弃的回忆——我的大学时代
  20. Android 购物车UI及逻辑实现

热门文章

  1. 几张产生视觉错觉的图片
  2. ArcMAP使用技巧小结
  3. python可爱代码,三分钟用Python带你画出一只可爱布朗熊
  4. 2021-2027全球与中国可变自耦变压器市场现状及未来发展趋势
  5. Python-bs4库,find_all 函数处理css样式问题
  6. Python-Flask开发微电影网站(五)
  7. 构成中学计算机教学系统的要素包括,教学策略就是对完成特定的教学目标而采用的教学活动的()要素的总体考虑...
  8. 通过实战测试无线网络的速度
  9. python爬取58上的招聘信息
  10. 1.27BSC什么意思?