Multidex 记录:缺陷解决、源码解析及使用介绍

2024-11-14 18:09:43

记录一:介绍及使用

记录2:缺陷及解决方案

记录3:源码分析

记录介绍及使用

为什么要使用记录?因为当我开始接触的时候我们的项目就已经到了65535的边缘了。很快就有了解决方案。我们已经连接很多年了,但我自己还没有连接过,所以这篇博文只是作者自己的访问记录,大部分来自官网。

图片.png

背景

随着平台的不断发展,应用程序的规模也在不断扩大。当您的应用程序及其引用的库达到一定大小时,您将遇到构建错误,表明您的应用程序已达到应用程序构建架构的限制。早期版本的构建系统报告此错误如下:

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

超过最大方法数限制的问题是由于DEX文件格式的限制。一个DEX文件中的方法数量使用原生类型short来索引文件,即2个字节最多可以表示65536,并且字段/类号的数量也受到这个限制。对于DEX文件来说,就是将项目所需的所有类文件合并压缩为一个DEX文件的过程,即打包DEX过程中,单个DEX文件可以引用的方法总数(self -开发的代码和引用的框架、库代码)仅限于65536个。

官方:超过64K配置方法的应用

5.0之前版本的可执行分包支持

5.0(API 级别 21)之前的平台版本使用运行时来执行应用程序代码。默认情况下,应用程序的每个 APK 仅限一个 .dex 字节码文件。要绕过此限制,您可以使用并管理对其他 DEX 文件及其包含的代码的访问。

5.0及更高版本的可执行分包支持

版本 5.0(API 级别 21)及更高版本使用名为 ART 的运行时,它本身支持从 APK 文件加载多个 DEX 文件。安装应用程序时,ART 会执行预编译,扫描 .dex 文件并将其编译为单个 .oat 文件以供设备执行。因此,如果你的版本是21或更高,则不需要可执行打包支持库。

目前的设备市场中,.0以下的手机仍然居多,所以我们需要使用65535来解决这些设备上的应用程序问题。

配置您的应用程序以进行可执行打包

将应用程序项目设置为使用可执行打包配置需要对应用程序项目进行以下修改,具体取决于应用程序支持的最低版本。

修改配置文件

如果您的设置为 21 或更高,您只需在模块级构建中将其设置为 true 即可。文件,如下所示:

android {
    defaultConfig {
        ...
        minSdkVersion 21 
        targetSdkVersion 26
        multiDexEnabled true
    }
    ...
}

但是,如果您的设置为 20 或更低,则构建脚本依赖项标识符将如下所示:

compile 'com.android.support:multidex:1.0.2'

修订



    
        ...
    

public class MyApplication extends MultiDexApplication { ... }

public class MyApplication extends SomeOtherApplication {
  @Override
  protected void attachBaseContext(Context base) {
     super.attachBaseContext(base);
     MultiDex.install(this);
  }
}

构建应用程序后,构建工具将根据需要构建主DEX文件(.dex)和辅助DEX文件(.dex、.dex等)。然后构建系统会将所有 DEX 文件打包到您的 APK 中。

在运行时,可执行打包 API 使用特殊的类加载器在所有 DEX 文件中搜索您的方法(而不是仅在主 .dex 文件中搜索)。

可执行打包支持库 java.lang 的限制。

由于每个 DEX 文件都被分包来构建可执行文件,因此构建工具会执行复杂的决策来确定主 DEX 文件中需要哪些类,以便应用程序可以成功启动。如果主 DEX 文件中未提供启动期间所需的任何类,您的应用程序将崩溃并出现错误 java.lang。

对于直接从应用程序代码访问的代码,不应发生这种情况,因为构建工具知道这些代码路径,但当代码路径的可见性较低时(例如使用具有复杂依赖项的库),可能会发生这种情况。例如,如果代码使用自省机制或从本机代码调用 Java 方法,则主 DEX 文件中可能无法识别这些类。

因此,如果您收到 java.lang.,则必须根据主 DEX 文件中的需要手动指定这些其他类,方法是使用构建类型中的 或 属性声明它们。如果类在 或 文件中匹配,则该类将添加到主 DEX 文件中。

财产

您指定的文件每行应包含一个类,格式为 com//.class。例如,您可以创建名为 -.txt 的文件,如下所示:

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

然后,您可以声明构建类型的文件,如下所示:

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

请记住,路径是相对于构建读取的。文件,因此如果 -.txt 与构建位于同一目录中,则上面的示例将起作用。文件。

财产

该文件使用与 相同的格式,并且支持整个语法。有关 ` 格式和语法的更多信息,请参阅手册中的 部分。

您指定的文件应包含任何有效语法中的 -keep 选项。例如,-keep com...class。您可以创建一个名为 -.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'
            ...
        }
    }
}

这就是本文的全部内容。如果您还有什么需要沟通的,请留言! !

如果您想阅读作者更多文章,可以查看我的个人博客和公众号:

DEX_dex交易所_dexterity翻译

振兴书店

首页
欧意注册
欧意下载
联系