频道栏目
首页 > 资讯 > 其他 > 正文

配置超过64K方法的应用程序

16-11-04        来源:[db:作者]  
收藏   我要投稿

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

这两个错误情况都显示一个常用的数字:65,536。 这个数字很重要,因为它代表单个Dalvik Executable(dex)字节码文件中的代码可以调用的引用的总数。 如果你已经构建了一个Android应用程序并收到此错误,那么恭喜你,你有很多代码! 本文介绍如何超越此限制并继续构建您的应用程序。

注意:本文中提供的指南取代了Android开发人员博客中Dalvik中的自定义类加载中给出的指导。

关于64K引用限制


Android应用程序(APK)文件包含Dalvik可执行文件(DEX)形式的可执行字节码文件,它包含用于运行应用程序的编译代码。 Dalvik Executable规范将单个DEX文件中可以引用的方法的总数限制为65,536,包括Android框架方法,库方法和您自己的代码中的方法。 在计算机科学的上下文中,术语Kilo,K表示1024(或2 ^ 10)。 因为65,536等于64 X 1024,所以此限制称为“64K引用限制”。

超过此限制要求您配置您的应用程序构建过程以生成多个DEX文件,称为multidex配置。

在Android 5.0之前的Multidex支持

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

注意:如果您的项目配置为使用minSdkVersion 20或更低版本的multidex,并且部署到运行Android 4.4(API级别20)或更低版本的目标设备,Android Studio将禁用即时运行

在Android 5.0之后的Multidex支持

Android 5.0(API级别21)和更高版本使用一个运行时称为ART,ART本身支持从应用程序APK文件加载多个dex文件。 ART在应用程序安装时执行预编译,扫描类(.. N).dex文件,并将它们编译为单个.oat文件以供Android设备执行。 有关Android 5.0运行时的详细信息,请参阅ART简介

注意:使用即时运行时,当您的应用程序的minSdkVersion设置为21或更高,Android Studio会自动将您的应用程序配置为multidex。 因为即时运行只适用于您的应用程序的调试版本,所以您仍然需要配置multidex的发布版本以避免64K限制。

避免64K限制


在配置应用以启用使用64K或更多方法引用之前,您应该采取措施减少应用代码调用的引用总数,包括由应用代码或包含的库定义的方法。 以下策略可帮助您避免达到dex参考限制:

查看您应用程式的直接和间接依赖项-在应用程序中包含依赖关的任何大型库的代码量大于被使用的量。 一个常见的反模式是程序包含一个非常大的库,但只有一些的方法是有用的。 减少应用程式依赖项通常可以避免dex引用限制。 使用ProGuard删除未使用的代码-为您的应用程序配置ProGuard设置以运行ProGuard,并确保已为发布版本启用缩减。 启用缩减功能可确保您不会使用APK传送未使用的代码。

使用Gradle配置Multidex应用程序


Android SDK中Gradle的Android插件Build Tools 21.1和更高版本支持multidex作为构建配置的一部分。 在尝试为multidex配置应用程序之前,请确保SDK Manager将Android SDK构建工具和Android支持存储库更新到最新版本。

将应用程序开发项目设置为使用multidex配置,需要对应用程序开发项目进行一些修改。 特别需要执行以下步骤:

更改Gradle构建配置以启用multidex 修改您的清单以引用MultiDexApplication类

修改模块级build.gradle文件配置以包括支持库并启用multidex输出,如以下代码段所示:

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

在您的清单中将MultiDexApplication类从multidex支持库添加到应用程序元素。



    
        ...
    

当这些配置设置添加到应用程序时,Android构建工具根据需要构造主要dex(classes.dex)和支持(classes2.dex,classes3.dex)。 构建系统然后将它们打包为APK文件以进行分发。

注意:如果应用程序使用扩展了Application类,则可以覆盖attachBaseContext()方法并调用MultiDex.install(this)以启用multidex。 有关详细信息,请参阅MultiDexApplication参考文档。

multidex支持库的局限性

multidex支持库有一些已知的限制,当合并到应用程序构建配置时应该注意和测试:

在启动过程中将.dex文件安装到设备的数据分区上非常复杂,如果辅助dex文件较大,可能导致应用程序无响应(ANR)错误。 在这种情况下,您应该使用ProGuard应用代码缩减技术,以最小化dex文件的大小和删除未使用的代码部分。 由于Dalvik linearAlloc错误(问题22586),使用multidex的应用程序可能无法在运行早于Android 4.0(API级别14)的平台的设备上启动。 如果您的目标API级别早于14,请确保使用这些版本的平台执行测试,因为您的应用程序在启动时或加载特定的类组时可能会出现问题。 代码缩减可以减少或可能消除这些潜在问题。 由于Dalvik linearAlloc限制(问题78035),使用使用非常大内存分配请求的multidex配置的应用程序可能在运行时崩溃。 Android 4.0(API级别14)中的分配限制已增加,但在Android 5.0(API级别21)之前的Android版本中,应用仍可能达到此限制。 对于在Dalvik运行时中执行时主要dex文件中需要什么类有复杂的要求。 Android构建工具更新处理Android需求,但是其他包含的库可能有额外的依赖性要求,包括使用自省或从本机代码调用Java方法。 在更新multidex构建工具之前,可能无法使用某些库,以允许您指定必须包含在主dex文件中的类。

优化Multidex开发构建


multidex配置要求大大增加构建处理时间,因为构建系统必须做出关于必须包括在主DEX文件中什么类以及哪些类可以包括在辅助DEX文件中的复杂决定。 这意味着使用multidex作为开发过程的一部分执行的常规构建通常需要更长时间,并且可能会减慢您的开发过程。

为了减少multidex输出的通常较长的构建时间,您应该使用Gradle productFlavors的Android插件在构建输出上创建两个变体:开发风格和生产风格。

对于开发风格,请设置最低SDK版本21.此设置使用ART支持的格式可以更快地生成multidex输出。 对于版本风格,请设置与实际最低支持级别匹配的最低SDK版本。 此设置会生成与更多设备兼容的multidex APK,但需要更长时间才能生成。

以下构建配置示例演示如何在Gradle构建文件中设置这些类型:

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

完成此配置更改后,您可以使用应用程序的devDebug变体,它结合了dev productFlavor和debug buildType的属性。 使用此目标创建一个调试应用程序,其中禁用proguard,启用multidex并将minSdkVersion设置为Android API级别21.这些设置使Android Gradle插件执行以下操作:

将应用程序的每个模块(包括依赖关系)构建为单独的dex文件。 这通常被称为预先dexing。 在APK中包含每个dex文件,而不进行修改。 最重要的是,模块dex文件不会被组合,因此避免了长期运行的计算,以确定主要dex文件的内容。

这些设置导致快速,增量构建,因为只有修改模块的dex文件被重新计算并重新打包到APK文件中。 从这些版本生成的APK只能用于在Android 5.0设备上测试。 但是,通过将配置实现为一个flavor,您可以保留使用适当的最低SDK级别和proguard设置执行正常构建的功能。

您还可以构建其他变体,包括prodDebug变体生成,它需要更长的构建,但可以用于在开发外测试。 在显示的配置中,prodRelease变体将是最终的测试和发布版本。 如果您从命令行执行gradle任务,则可以使用带有附加到其后的DevDebug的标准命令(例如./gradlew installDevDebug)。 有关使用Gradle任务使用flavor的更多信息,请参阅Gradle插件用户指南

提示:您还可以为每个flavor提供自定义清单或自定义应用程序类,从而允许您使用支持库MultiDexApplication类,或仅对需要它的变体调用MultiDex.install()。

在Android Studio中使用构建变体

构建变量对于在使用multidex时管理构建过程非常有用。 Android Studio允许您在用户界面中选择这些构建版本。

要让Android Studio构建应用程序的“devDebug”变体:

从左侧栏中打开Build Variants 窗口。 选择Favorites。 单击构建变量的名称以选择其他变体,如图1所示。

图1. Android Studio左侧面板的屏幕截图,显示了构建版本。

注意:打开此窗口的选项仅在Tools > Android > Sync Project with Gradle Files命令成功同步Android Studio与Gradle构建文件后可用。

Multidex应用程序测试


为multidex应用程序编写测试测试时,不需要其他配置。 AndroidJUnitRunner支持multidex白盒测试,只要在自定义Application对象中使用MultiDexApplication或覆盖attachBaseContext()方法,并调用MultiDex.install(this)即可启用multidex。

或者,您可以覆盖AndroidJUnitRunner中的onCreate()方法:

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

注意:目前不支持使用multidex创建测试APK。

相关TAG标签
上一篇:Java设计模式之——状态模式
下一篇:指尖菜谱App从0到1-项目初次开发
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站