Android MultiDexApplication 为方法数超过 64K 的应用启用 MultiDex 总结记录

本文介绍如何为方法数超过64K的应用启用MultiDex,包括不同Android版本的配置方法,以及规避64K限制的策略。

为方法数超过 64K 的应用启用 MultiDex

当您的应用及其引用的库包含的方法数超过 65536 时,您会遇到一个构建错误,指明您的应用已达到 Android 构建架构规定的引用限制:

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

较低版本的构建系统会报告一个不同的错误,但指示的是同一问题:

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

这两种错误情况会显示一个共同的数字:65536。此数字是单个 Dalvik Executable (DEX) 字节码文件内的代码可调用的引用总数

关于64K引用限制

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

Android 5.0 之前版本的 MultiDex 支持

dependencies {
    def multidex_version = "2.0.1"
    implementation 'androidx.multidex:multidex:$multidex_version'
}

非AndroidX 版本

dependencies {
  implementation 'com.android.support:multidex:1.0.3'
}

Android 5.0及更高版本的 MultiDex 支持

Android 5.0(API 级别 21)及更高版本使用名为 ART 的运行时,它本身支持从 APK 文件加载多个 DEX 文件。ART 在应用安装时执行预编译,扫描 classesN.dex 文件,并将它们编译成单个 .oat 文件,以供 Android 设备执行。因此,如果您的 minSdkVersion 为 21 或更高的值,则默认情况下会启用 MultiDex,并且您不需要 MultiDex 支持库。

规避64K 限制

1.检查应用的直接依赖项和传递依赖项 - 确保您在应用中使用任何庞大依赖库所带来的好处多于为应用添加大量代码所带来的弊端。一种常见的反面模式是,仅仅为了使用几个实用方法就在应用中加入非常庞大的库。减少应用代码依赖项往往能够帮助您规避 DEX 引用限制。
2. 通过 R8 移除未使用的代码 - 启用代码缩减以针对发布 build 运行 R8。启用缩减可确保您交付的 APK 不含有未使用的代码。

具体配置

如果您的 minSdkVersion 设为 21 或更高的值,则默认情况下会启用 MultiDex,并且您不需要 MultiDex 支持库。

不过,如果您的 minSdkVersion 设为 20 或更低的值,则必须使用 MultiDex 支持库并对应用项目进行以下修改:

  1. 修改模块级 build.gradle 文件以启用 MultiDex,并将 MultiDex 库添加为依赖项,如下所示:
android {
    defaultConfig {
        ...
        minSdkVersion 15
        targetSdkVersion 28
        multiDexEnabled true
    }
    ...
}

dependencies {
  implementation 'com.android.support:multidex:1.0.3'
}
  1. 根据您是否替换 Application 类,执行以下某项操作:
  • 如果您不替换 Application 类,请修改清单文件以设置 标记中的 android:name,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <application
            android:name="android.support.multidex.MultiDexApplication" >
        ...
    </application>
</manifest>
  • 如果您替换 Application 类,请对其进行更改以扩展 MultiDexApplication(如果可能),如下所示:
class MyApplication : MultiDexApplication() {...}
  • 或者,如果您替换 Application 类,但无法更改基类,则可以改为替换 attachBaseContext() 方法并调用 MultiDex.install(this) 以启用 MultiDex:
class MyApplication : SomeOtherApplication() {

    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(base)
        MultiDex.install(this)
    }
}

官方文档链接地址

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值