MultiDex 官方教你解决64K方法

官网地址: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这个插件来做到以下几点:

  1. 建设作为单独的DEX文件的应用程序(包括依赖)的每个模块。这通常被称为预德兴。
  2. 包括不加修改地在每个APK文件DEX。
  3. 最重要的是,模块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. 打开生成变种从左边的侧边栏的窗口。该选项旁边的 收藏夹
  2. 单击构建变量的名称,以选择一个不同的变型中,如图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测试使用。

时间: 2024-11-02 07:07:01

MultiDex 官方教你解决64K方法的相关文章

教你解决Sublime Text中文乱码问题

前面一篇开始学习solr的时候,做了个入门的示例http://blog.csdn.net/zjc/article/details/24414271 .虽然可以检索出内容,但总和想象的结果有差异--比如,检索"天龙"两个字,按常规理解,就应该只出来<天龙八部>才对,可是竟然也会把<倚天屠龙记>检出来.后来研究了一下,发现系统是这样处理的:无论是抽索引时还是分析检索词时,都把所有文字按单字拆开.这样,刚好<倚天屠龙记>里包含"天"和&

【XS128】Link error L1822 symbol _FADD / _FSUB/ _FDIV/ _FMUL.....错误解决的方法

转载请注明出处 因为阅历有限,篇幅不周之处还望指出,谢谢 假设方法确实奏效,请一定回复点赞哦,给后来人也是一种帮助,谢谢! 这是飞思卡尔 XS128平台比較常见的LINK错误. 可是要解决起来也比較头疼. 非常多人或许有这种经历,整个project文件夹是在别人做过的全部文件拷贝过来然后改动代码符合自己项目要求而产生的.这就发生了一个问题, 当初新建project时的非常多配置,比方预处理器配置,就会出现不适用当前项目.比方,本文所要提到的链接错误. 这个发生错误于: 原project在新建的时

demopu教你解决centos系统故障-去除虚拟机Linux的“嘟嘟”报警声

demopu教你解决centos系统故障-去除虚拟机Linux的“嘟嘟”报警声 转载:http://www.demopu.com/?p=472 Vmware上装的Redhat,在Shell下由于输错命令或是种种原因,会发出“嘟嘟”的报警声,并不是声卡发出的,而是主板的报警,所以不能通过关闭音箱来解决.办公室里经常响起这样的声音非常刺耳,今天在网上找到了解决方法,记下: 将/etc/inputrc中的set bell-style none 前的#去掉,重新登陆即可. 转载请注明:Demopu.co

Firefly官方教程之DBentrust使用文档

1.dbentrust说明 该模块主要是对数据库与memcached存储的处理.里面封装了从memcached数据到python对象的映射.可以以操纵python对象的方式进行memcached中存储的数据的操作,只要在不同的进程中实例化相同名称的memobject对象,就能保证对象中的数据是一致的.还包含了将这个对象中的数据同步到数据库的处理方法. 2.结构解析 <ignore_js_op> MemObject类规定了数据的格式,所有的数据都存储在memcached中,为了区分不同的数据,每

Firefly官方教程之Distributed使用文档

distributed使用文档1.distributed说明该模块主要封装了各个服务进程间进行通信的方法.node子节点域root根节点进程中的接口调用返回的都是延迟对象.关于延迟对象的使用,详见twisted中Deferred对象.2.结构解析 <ignore_js_op> PBRoot,root节点对象ChildsManager,子节点管理基类Child对象对应的是连接到本服务进程的某个服务进程对象.称为子节点对象RemoteObject远程调用对象,子节点服务进程中实现.可以通过这对象去

C#开发Unity游戏教程之Unity中方法的参数

C#开发Unity游戏教程之Unity中方法的参数 Unity的方法的参数 出现在脚本中的方法,无论是在定义的时候,还是使用的时候,后面都跟着一对括号“( )”,有意义吗?看起来最多也就是起个快速识别方法的作用吧.既然C#的语法规定方法就应该这么写,肯定是有一定道理的.如果是上升到战略意义的道理,连作者也不是很明白,但是作者知道这对括号里可以添加“参数”. Unity中参数的作用 要说明参数的作用,就必须从方法说起.方法可以处理变量中的数据,进而影响游戏对象的行为逻辑,这是本章前面一直在强调的.

Android ROM开发(二)——ROM架构以及Updater-Script脚本分析,常见的Status错误解决的方法

Android ROM开发(二)--ROM架构以及Updater-Script脚本分析,常见的Status错误解决的方法 怪自己二了.写好的不小心弄没了,如今仅仅好又一次写一些了.上篇简单的配置了一下环境.这里呢,就来讲一下相关的仅仅是点 我们先下载一个ROM.随便下,原理都是差点儿相同的,这里我就下载一个红米Note的MIUI稳定版 1.ROM结构 ROM依据厂商的定制可能有所不同,可是大体是不变的 data 内置一些软件 META-INF 脚本文件 update-binary 二进制文件 u

Firefly官方教程之Netconnect使用文档

1.distributed说明该模块包含了服务端与客户端通信的一些处理方法,包括发送数据的封装,协议头的封装,tcp通信时进行分包,处理粘包问题.2.结构解析 LiberateFactory,协议工厂,所有连接的本质,服务端与客户端通信的这一行为的形象化,它包含三个部分:1)LiberateProtocol,通信协议类,连接建立.断开后的操作,发送数据等都由它来控制2)DataPackProtoc,数据包协议的定义,所有的数据解析都要遵守它定制的规则3)ConnectionManager,连接管

python 遇到 syntaxerror: non-ascii character &#39;/xd6&#39; in file 我 教你解决 (python问题)(转)

遇到标题上的问题,按照我的解决广方案来吧 ===================================== (一) 用记事本创建一个文件ChineseTest.py,默认ANSI: s = "中文" print s测试一下瞧瞧: E:/Project/Python/Test>python ChineseTest.py File "ChineseTest.py", line 1 SyntaxError: Non-ASCII character '/xd