AndroidStudio-解决单个dex 64K接口限制

解决单个dex 64K接口限制

  • 1、概述
  • 2、关于64K接口限制
  • 3、避免64K接口的限制
  • 4、多dex的一些配置
  • 5、编译时优化多dex
  • 6、测试多dex app

1、概述

当app和依赖的库,所有的接口数超过65536,编译时会遇到错误,提示接口超过了限制,log如

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

老版本编译系统会报一个不同形式的错误log

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

这两种形式的log都有一个相同的数字:65536。这个数字代表了单个虚拟机执行DEX文件可调用接口的最大数。本文解释如何通过多dex文件解决之前的接口限制,使app可以编译和读多dex文件。

2、关于64K接口限制

Android app包含虚拟机执行的DEX格式的bytecode文件,该文件是编译代码所得。虚拟机执行规范规定了单个dex文件包含的最大接口数为65536,这些接口可以是:Android framework接口、库接口、app接口。

  • Android5.0之前版本支持多dex
dependencies {
    def multidex_version = "2.0.1"
    implementation 'androidx.multidex:multidex:$multidex_version'
}

如果要看库的当前版本,在version页面查看Multidex。
如果不使用AndroidX,使用下面的库代替

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

这个库会成为主dex文件的一部分,用来管理其他的dex文件和获取其中的代码。

  • Android5.0及之上版本支持多dex
    Android5.0及之上版本,系统使用ART,ART天然的支持从app加载多dex文件。在app安装前,ART会对没有个dex文件做预处理,合并为一个运行时使用的.oat的文件。所以,minSdkVersion高于21的app默认支持多dex,在编译时无需增加支持多dex的依赖库。
    注意: 当使用AndroidStudio运行app时,默认会针对部署的设备做优化,优化包括目标设备使用系统为Android5.0或之上时支持多dex。这种优化仅在使用AndroidStudio部署app时,因此,在编译release版本时,需要配置支持多dex。

3、避免64K接口的限制

在使能多dex支持前,尽量减少app和库的接口,使用以下策略帮助避免遭遇dex接口限制:

  • 检查app直接或间接的依赖库。确定任何一个很大的很可能会引入很多接口的依赖库是必须的;另一种不好的情况是,一个很大的依赖库却只用了很少的几个接口。尽可能的减少app代码中对其他库的依赖,来减少dex文件的接口。
  • 使用R8删除不使用的代码。release版本打开压缩代码功能,代码压缩功能可以移除apk不使用的代码。

使用这些技术可以帮助避免使用多dex同时减小apk的整体大小。

4、多dex的一些配置

Android5.0及以上版本已默认支持,无需额外配置,低版本系统已经很少,因此这里不做说明。
若需了解,参考“Enable multidex”的Configure your app for multidex章节。

5、编译时优化多dex

支持多dex的app编译时,会明显的增加编译时间,因为在编译时有一个复杂的决定过程,需要决定哪些class放在主dex,哪些class可以放在非主dex中。这意味着使用多dex而增加的编译可能会延长开发周期。
为了缓和增加的时间,在多次编译间使用dex预处理,减少多dex输出需要的时间。dex预处理依赖Android5.0及之上版本支持的ART。如果AndroidStudio版本为2.3或更高,在Android5.0及之上版本,编译时自动使用预处理功能。
注意: Android gradle插件3.0及更高版本有改善编译速度的特性,如每个class文件做dex处理,当class文件被修改了,才会再次做dex。通常情况下,最佳的开发体验是,及时更新AndroidStudio和插件为最新。
如果使用命令行编译app,需要在脚本中配置minSdkVersion为21或更高,以使支持编译dex预处理。一个有用的策略是增加一个编译变体,在编译变体中配置minSdkVersion。示例如下:

android {
    defaultConfig {
        ...
        multiDexEnabled true
        // The default minimum API level you want to support.
        minSdkVersion 15
    }
    productFlavors {
        // Includes settings you want to keep only while developing your app.
        dev {
            // Enables pre-dexing for command line builds. When using
            // Android Studio 2.3 or higher, the IDE enables pre-dexing
            // when deploying your app to a device running Android 5.0
            // (API level 21) or higher—regardless of what you set for
            // minSdkVersion.
            minSdkVersion 21
        }
        prod {
            // If you've configured the defaultConfig block for the production version of
            // your app, you can leave this block empty and Gradle uses configurations in
            // the defaultConfig block instead. You still need to include this flavor.
            // Otherwise, all variants use the "dev" flavor configurations.
        }
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'),
                                                 'proguard-rules.pro'
        }
    }
}
dependencies {
    implementation 'com.android.support:multidex:1.0.3'
}

注意: 当编译app的最低版本不小于21,命令行编译也无需新增编译变体。

6、测试多dex app

当使用instrumentation tests测试多dex app时,使用MonitoringInstrumentation (or an AndroidJUnitRunner) instrumentation无任何附加配置。如果使用Instrumentation,必须重写onCread且添加如下代码

public void onCreate(Bundle arguments) {
  MultiDex.install(getTargetContext());
  super.onCreate(arguments);
  ...
}

你可能感兴趣的:(AndroidStudio)