官网地址:http://developer.android.com/tools/building/multidex.html 大概意思翻译一下,不是逐词逐句,意会意会。。
由于Android平台的持续增长,Android应用程序的大小也随之增大。当你的应用程序引用库达到一定的规模,就会出错(64K):
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可执行(DEX)字节码文件中调用的引用的总数显著。如果你已经建立了一个Android应用程序,并收到此错误,那么恭喜你,你有很多的代码!本文档介绍了如何将突破这个限制,并继续构建应用程序。
注:本文档中提供的指导取代了Android开发者博客中给予的指导自定义类加载在Dalvik的。
关于64K参考限值
Android应用(APK)文件包含形式的可执行字节码文件的Dalvik 可执行文件(DEX)文件,其中包含用于运行你的应用程序的编译代码。在Dalvik可执行的规范限制了可以在单个文件DEX内引用到65536,包括Android框架方法,库方法,并在自己的代码方式方法的总数。在计算机科学的上下文中,术语基洛,K,表示1024(或2
^ 10)。因为65,536等于64×1024,这个限制被称为‘64K参考限制‘。
获得过去此限制,您需要配置您的应用程序的构建过程,生成多个文件DEX,被称为multidex配置。
Multidex支持到Android 5.0之前
之前的Android 5.0(API级别21)平台的版本,用于执行应用程序代码的Dalvik运行。默认情况下,Dalvik的限制应用到每个APK一个classes.dex字节码文件。为了解决这个限制,可以使用multidex支持库,成为您的应用程序的主DEX文件的一部分,然后设法获得额外的DEX文件和它们所包含的代码。
注意:如果您的项目配置为multidex用 的minSdkVersion 20
或更低,并且部署到目标运行Android 4.4(API级别20)或更低的设备,Android Studio中禁用即时运行。
为Android 5.0及更高版本Multidex支持
是Android 5.0(API级别21)和较高的使用一种称为ART运行时它本身支持与应用程序APK文件加载多个DEX文件。ART在应用程序执行预编译安装时它会扫描类(.. N).dex文件,并将其编译成由Android设备执行单一.oat文件。对于在Android 5.0运行时的更多信息,请参见介绍ART。
注意:在使用即时运行,当你的应用程序的Android
Studio自动配置您的应用multidex 的minSdkVersion
设置为21或更高。由于即时只运行与您的应用程序的调试版本的作品,你还需要为multidex配置您的发布版本,以避免64K限制。
避免64K限制
在配置您的应用程序,以便使用64K或以上方法的引用,您应该采取措施,以减少你的应用程序代码调用引用的总次数,包括您的应用程序代码或包含的库定义的方法。以下策略可以帮助您避免击中DEX参考限值:
- 查看应用的直接和传递依赖 -确保任何大库的依赖关系,你在应用程式的方式,胜过的代码量被添加到应用程序中使用。一个常见的反模式是包含一个非常大的图书馆,因为一些实用的方法是有用的。减少你的应用程序代码依赖性往往可以帮助你避免DEX参考限值。
- 使用ProGuard删除未使用的代码 -配置ProGuard的为您的应用程序的设置来运行ProGuard,并将其确定您已经缩水启用发布版本。启用萎缩确保你不发货未使用的代码与您的APK。
使用这些技术可以帮助您避免使你的应用更加方法引用所需的生成配置的变化。这些步骤还可以降低你的APK,这对其中带宽成本很高的市场尤为重要的规模。
配置您的Multidex与Gradle
在Android SDK中提供的Android插件的摇篮构建工具21.1和更高版本支持multidex作为构建配置的一部分。请确保您更新了Android SDK构建工具工具和Android的支持库使用最新版本的SDK经理尝试配置您的应用multidex之前。(
(上边的都是废话,下边是解决方法————————————————————————————————————————————————————————————)
设置您的应用开发项目中使用multidex配置要求你做一些修改您的应用程序开发项目。特别需要执行以下步骤:
- 改变你的Gradle构建配置,使multidex
- 修改你的清单来引用
MultiDexApplication
类
修改模块级的build.gradle
文件配置包括支持库,使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‘ }
在您的清单中添加的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文件启动期间安装到设备的数据分区是复杂的,并可能导致在应用无响应(ANR)错误如果二次DEX文件是大的。在这种情况下,你应该申请代码缩减技术使用ProGuard尽量减少DEX文件的大小,并删除代码的未使用的部分。
- 使用multidex可能无法运行由于Dalvik的linearAlloc错误(发行早于Android 4.0的(API级别14)平台版本的设备开始应用22586)。如果你是早于14
API目标水平,确保执行与这些版本的平台测试您的应用程序可以在启动时的问题或当类特殊群体被加载。代码收缩可以减少或可能消除这些潜在的问题。 - 使用multidex配置,使非常大的内存分配请求的应用程序可能在运行时由于Dalvik的linearAlloc限制(第崩溃78035)。此分配限制是在Android 4.0的(API级别14)增加,但应用仍有可能之前的Android
5.0(API级别21)碰上在Android版 ??本中此限制。 - 有关于在Dalvik运行时中执行时需要什么样的课程列入小学DEX文件复杂的要求。Android编译工具的更新处理Android的要求,但它可能是其他包括图书馆有额外的依赖性要求,包括使用内省或Java方法调用的本地代码。直到multidex构建工具的更新,使您可以指定必须包括在主DEX文件类,某些库可能无法使用。
优化Multidex开发版本
一个multidex配置要求显著上升构建的处理时间,因为构建系统必须做出什么类必须包含在主DEX文件,哪些类可以包含在二次DEX文件复杂的决定。这意味着,常规建立与multidex发展过程的一部分执行通常需要更长的时间,并有可能减缓您的开发过程。
为了减轻通常较长的建立multidex输出时间,你应该创建使用摇篮的Android插件构建输出两种变化 productFlavors
:开发风味和生产的味道。
对于开发味,设置一个最小的SDK版本21.此设置更快产生multidex输出采用ART-支持的格式。对于释放香味,设置符合你的实际的最低支持率的最低SDK版本。此设置生成APK multidex是与更多的设备兼容,但需要更长的时间来建立。
下面构建配置示例演示了如何设置这些味道在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 true proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘ } } } dependencies { compile ‘com.android.support:multidex:1.0.0‘ }
完成此配置更改后,您可以使用devDebug
您的应用程序,它结合了属性的变异开发
productFlavor和 调试
buildType。使用此目标创建了ProGuard的残疾人,multidex调试应用程序启用,并设置的minSdkVersion到Android API 21级这些设置导致了Android
gradle这个插件来做到以下几点:
- 建设作为单独的DEX文件的应用程序(包括依赖)的每个模块。这通常被称为预德兴。
- 包括不加修改地在每个APK文件DEX。
- 最重要的是,模块DEX文件将不会合并,所以长期运行计算来确定主DEX文件的内容是可以避免的。
这些设置会导致快速,增量编译,因为只有修改模块的DEX文件重新计算和重新包装成APK文件。从这些结果APK建立可用于仅5.0设备在Android上进行测试。然而,通过实现配置作为香味后,将保留执行正常的生成与释放,适当的最低水平SDK和ProGuard的设置的能力。
还可以构建其它变体,包括一个prodDebug
变种的构建,这需要更长的时间来建立,但可以用于测试开发之外。在所示的配置中,prodRelease
变异将是最后的测试和发布版本。如果您在命令行中执行任务的gradle,你可以使用标准的命令DevDebug
追加到结尾(例如./gradlew installDevDebug
)。有关使用香精与摇篮任务的详细信息,请参阅 摇篮Plugin用户指南。
提示:您还可以提供定制清单,或每个口味的自定义应用程序类,允许您使用支持库MultiDexApplication类,或调用MultiDex.install()只对需要它的变种。
使用Build变种Android Studio中
构建变种可以使用multidex时,管理构建过程非常有用的。Android Studio中,您可以选择在用户界面构建这些变种。
有Android Studio中建立自己的应用程序的“devDebug”变种:
- 打开生成变种从左边的侧边栏的窗口。该选项旁边的 收藏夹。
- 单击构建变量的名称,以选择一个不同的变型中,如图1。
图1.在Android工作室的屏幕截图左图显示出构建变量。
注:打开此窗口中的选项只在您成功同步的Android Studio和使用您的摇篮构建文件后工具> Android的>同步工程与摇篮文件命令。
测试Multidex应用
当使用仪器测试,multidex应用程序,则需要额外的配置,以使测试仪器。由于代码在multidex应用类的位置不是一个单一的DEX文件内,仪表测试不正确除非配置为multidex运行。
为了测试与仪器测试中multidex应用,配置 MultiDexTestRunner从multidex测试支持库。下面的示例 的build.gradle
文件演示了如何配置您的构建来使用这个测试运行:
android { defaultConfig { ... testInstrumentationRunner "com.android.test.runner.MultiDexTestRunner" } }
注:借助Android插件Gradle版本低于1.1时,您需要添加以下依赖于multidex的仪器
:
dependencies { androidTestCompile(‘com.android.support:multidex-instrumentation:1.0.1‘) { exclude group: ‘com.android.support‘, module: ‘multidex‘ } }
您可以直接使用仪器测试运行的类或扩展,以满足您的测试需求。或者,您可以在这样现有的仪器仪表覆盖的onCreate:
public void onCreate(Bundle arguments) { MultiDex.install(getTargetContext()); super.onCreate(arguments); ... }
注:目前不支持multidex创建APK测试使用。