关于Android65535的引用限制

作者: 钟金宝 | 来源:发表于2017-09-02 10:34 被阅读30次

关于 64K 引用限制

随着 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.

相信这个错误大多是的Android开发者都遇到过,解决办法也是比较简单的,只要引入MultiDexApplication即可。

具体出现这个问题的原因是:

Android打包发布的时候会将所有的class都打包进一个.dex文件中。
Android 应用 (APK) 文件包含 Dalvik Executable (DEX) 文件形式的可执行字节码文件,其中包含用来运行您的应用的已编译代码。Dalvik Executable 规范将可在单个 DEX 文件内可引用的方法总数限制在 65,536,其中包括 Android 框架方法、库方法以及您自己代码中的方法。在计算机科学领域内,术语千(简称 K)表示 1024(或 2^10)。由于 65,536 等于 64 X 1024,因此这一限制也称为“64K 引用限制”。

Android 5.0 之前版本的 Dalvik 可执行文件分包支持

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

Android 5.0 及更高版本的 Dalvik 可执行文件分包支持

在5.0以上Android默认支持

Android 5.0(API 级别 21)及更高版本使用名为 ART 的运行时,后者原生支持从 APK 文件加载多个 DEX 文件。ART 在应用安装时执行预编译,扫描 classesN.dex 文件,并将它们编译成单个 .oat 文件,供 Android 设备执行。因此,如果您的 minSdkVersion 为 21 或更高值,则不需要 Dalvik 可执行文件分包支持库。

声明主 DEX 文件中需要的类

为 Dalvik 可执行文件分包构建每个 DEX 文件时,构建工具会执行复杂的决策制定来确定主要 DEX 文件中需要的类,以便应用能够成功启动。如果启动期间需要的任何类未在主 DEX 文件中提供,那么您的应用将崩溃并出现错误 java.lang.NoClassDefFoundError

该情况不应出现在直接从应用代码访问的代码上,因为构建工具能识别这些代码路径,但可能在代码路径可见性较低(如使用的库具有复杂的依赖项)时出现。例如,如果代码使用自检机制或从原生代码调用 Java 方法,那么这些类可能不会被识别为主 DEX 文件中的必需项。
因此,如果您收到 java.lang.NoClassDefFoundError
,则必须使用构建类型中的 multiDexKeepFile
multiDexKeepProguard
属性声明它们,以手动将这些其他类指定为主 DEX 文件中的必需项。如果类在 multiDexKeepFile
或 multiDexKeepProguard
文件中匹配,则该类会添加至主 DEX 文件。

multiDexKeepFile 属性

您在 multiDexKeepFile 中指定的文件应该每行包含一个类,并且采用 com/example/MyClass.class 的格式。例如,您可以创建一个名为 multidex-config.txt 的文件,如下所示:

com/example/MyClass.class
com/example/MyOtherClass.class

然后,您可以按以下方式针对构建类型声明该文件:

android {
    buildTypes {
        release {
            multiDexKeepFile file 'multidex-config.txt'
            ...
        }
    }
}
multiDexKeepProguard 属性

multiDexKeepProguard
文件使用与 Proguard 相同的格式,并且支持整个 Proguard 语法。如需了解有关 Proguard 格式和语法的详细信息,请参阅 Proguard 手册中的 Keep Options 一节。
您在 multiDexKeepProguard
中指定的文件应该在任何有效的 ProGuard 语法中包含 -keep
选项。例如,-keep com.example.MyClass.class
。您可以创建一个名为 multidex-config.pro
的文件,如下所示:

-keep class com.example.MyClass
-keep class com.example.MyClassToo

如果您想要指定包中的所有类,文件将如下所示:

-keep class com.example.** { *; } // All classes in the com.example package

然后,您可以按以下方式针对构建类型声明该文件:

android {
    buildTypes {
        release {
            multiDexKeepProguard 'multidex-config.pro'
            ...
        }
    }
}

相关文章

  • 关于Android65535的引用限制

    关于 64K 引用限制 随着 Android 平台的持续成长,Android 应用的大小也在增加。当您的应用及其引...

  • 配置方法数超过 64K 的应用

    关于 64K 引用限制 是指单个DEX文件内可引用的方法总数不超过65,536,即64 X 1024,所以称为64...

  • 64K 引用限制

    概述 Android 应用 (APK) 文件包含 Dalvik Executable (DEX) 文件形式的...

  • android MultiDex分包

    参考 64k限制 Dalvik Executable 规范将可在单个 DEX 文件内可引用的方法总数限制在 65,...

  • 关于引用

    你要相信,你能提出来的绝大多数问题,在人类这几千年的经验和思考的历史里,一定会有先人提出过;更要相信,连你都能想得...

  • 关于“引用”

    周老师认为,引用成为习惯,就会懒于思考。 这点,我非常认同。 以前的文章,为了加强说服力,常常引用。 一大段名人名...

  • 关于限制

    关于限制 这两天在读史铁生的《病隙碎笔》,关于残疾与爱情,关于限制。 今天去散步的时候看到一只大型犬被关在...

  • Android65535问题 multiDexKeepFi

    https://developer.android.com/studio/build/multidex.html#...

  • rust 所有权

    不可变变量 可变变量 所有权三个规格 内存与分配 MOVE COPY 所有权和函数 引用与借用 可变引用的限制 引用悬挂

  • c++引用类型作为函数形参

    所以,临时变量不能作为非const引用参数,不是因为他是常量,而是因为c++编译器的一个关于语义的限制。如果一个参...

网友评论

    本文标题:关于Android65535的引用限制

    本文链接:https://www.haomeiwen.com/subject/tyiljxtx.html