本文翻译自http://developer.android.com/intl/zh-cn/tools/building/multidex.html#about。主要介绍当我们Android App中函数超过65536时构建失败的原因及解决办法!

   -------------------------分割线--------------------------------------------------

      随着android platform的持续增长,android apps的大小也在增长。当你的应用程序包括其所引用的库达到一定的规模,你将遇到构建错误,这表明你的程序已经达到到了android 应用框架的限制。在早期的构建系统会报告如下错误信息:

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

      最近版本的构建系统会显示不同的错误,这是同一个问题的提示信息:

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

      这两种错误情况显示了一个共同的数字:65536。这个数字代表的是单个Dalvik可执行的(DEX)字节码文件的可以调用方法总数。如果你已经创建了android应用,并且收到了这个错误,那么恭喜你,你的代码太多了!本文档将介绍如何突破这个限制,继续构建你的app

 About the 65K Reference Limit

      APK文件包含用于运行你的应用程序编译代码形式的可执行字节码文件(Dalvik Executable DEX)。Dalvik可执行的规范限制了在一个单一的DEX文件中引用到包括Android框架方法,库方法等方法的总数为65,536。想要突破此限制,您需要配置您的应用程序的构建过程,生成多个DEX文件,被称为multidex配置。

 Multidex support prior to Android 5.0

      Android5.0之前的版本使用的Dalvik运行时执行应用程序代码。默认情况下,Dalvik的限制的应用程序,每APK一个classes.dex字节码文件。为了解决这个限制,可以使用multidex support library,成为您的应用程序的主DEX文件的一部分,然后设法获得了额外的DEX文件和它们所包含的代码。

 Multidex support for Android 5.0 and higher

     Android5.0以及更高版本使用的是ART runtime,可以支持原生从APK文件中加载多个dex文件。ART进行预编译的应用程序安装时它会扫描类(.. N.dex文件,并通过Android设备编译成一个单一的.oat文件执行。对于在Android5.0运行时的详细信息,请参考 Introducing ART

 Avoiding the 65K Limit

     在配置您的应用程序能够使用65K+方法个数之前,您应该采取措施来减少您的应用程序代码调用引用的总数,包括您的应用程序代码中的方法和库定义的方法。以下策略可以帮助您避免超过DEX参考限值:

     看您的应用程序的直接和间接性依赖:确保在你的app中包含的library的用途要和其代码量匹配。一个比较常见的反例就是包含巨大的代码量,用途却很小。减少你的applibrary依赖往往可以帮你避免dex reference限制。

     删除未使用的代码混淆(code with ProGuard配置可以运行你的appProGuard并确保可以在正式构建程序的时候为你的程序瘦身。 

     使用这些技术可以帮助你避免更改程序构建配置时需要启用更多的方法引用。对于宽带成本很高的市场来说,这些步骤很重要。

 Configuring Your App for Multidex with Gradle

      Android插件Gradle Android SDK Build Tools 21.1和更高版本中支持multidex作为构建配置的一部分。在为你app配置multidex之前,请先使用SDK ManagerAndroid SDKBuild Tools Android Support Repository更新到最新版本。

      在你的app中使用multidex配置之前,需要对你的程序开发做一些相应修改。你需要执行以下步骤:

      1.修改你的 Gradle构建配置以启用multidex

      2.修改你的AndroidManifest 去引用MultiDexApplication class。

修改build.gradle配置去引用support library和启用multidex输出,如以下所示build.gradle片段

 

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'
}

 

      Note:你可以在build.gradle文件的defaultConfig,buildType,或者productFlavor中设置multiDexEnable。

      在你的AndroidManifestapplication元素中添加MultiDexApplication class:

<?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中。

      Note: 如果你的app使用了自己定义的Application class,你可以重写attachBaseContext()方法并在其中调用MultiDex.install(this)去实现multidex。更多信息请参考MultiDexApplication 

 Limitations of the multidex support library

      你应该意识到multidex support library有一些已知的限制,所以当你在将他合并到你的应用程序中时需要测试一下:

      1..dex文件的安装在启动设备的数据分区很复杂,如果二级dex文件太大可能导致程序没有响应(ANR)。在这种情况下,您应与混淆器(ProGuard)应用代码缩减技术,减少.dex文件的大小和删除未使用的部分代码。

      2.程序不能在在早已Android4.0API level 14)之前的版本上使用multidex由于a Dalvik linearAlloc bugIssue 22586)(http://b.android.com/22586)如果你使用API Level 14之前的版本,确保执行您的应用程序在启动时或者装载特定的类时,测试你的程序是否会出现问题。代码缩减可以消除这些潜在问题。

      3.应用程序使用multidex配置会发出非常大的内存分配请求,这可能会导致运行时崩溃,由于a Dalvik linearAlloc bugIssue 78035)(http://b.android.com/78035)。

      4.Dalvik runtime执行时the primary dex文件可能需要复杂的请求。Android build tooling 更新处理Android需求,但是其他included libraries可能有额外的依赖需要,包括调用本地的java代码。一些library可能无法使用,直到multidex build tools更新后允许您指定必须包含在主dex文件的类。 

 Optimizing Multidex Development Builds

      multidex配置需要显著增加构建处理时间,因为构建系统必须做出复杂决定,来确定哪些类必须包含在主dex文件以及哪些类可以包含在第二级dex文件中。这意味着常规构建执行与multidex作为开发过程的一部分,通常需要更长的时间,这可能减缓你的程序开发进度。

      为了减少multidex输出构建时间,你应该创建两个变量来使用Android构建输出插件Gradle productFlavors: a development flavor and a production flavor

a development flavor,设定一个最低21SDK版本。这个设置生成multidex输出比使用ART-supported格式要快得多。the release flavor,设定一个最低SDK版本匹配你的项目最低支持版本。这个设置生成一个multidex APK,与更多的设备兼容,但需要更长的时间来构建。

      以下构建配置示例演示了如何在Gradle构建文件设置这些 flavors :

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'
}
View Code

相关文章:

  • 2021-10-29
  • 2022-12-23
  • 2021-06-21
  • 2022-12-23
  • 2021-11-14
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-08-09
  • 2022-12-23
  • 2021-11-03
相关资源
相似解决方案