构建超过65535方法数的安卓程序

本文译自http://developer.android.com/tools/building/multidex.html#about


构建超过65536方法数的安卓程序

 随着安卓平台的不断发展,安卓应用的大小也在不断增加。当你的应用和引用库的大小达到了一定的规模,你会遇到构建的错误,错误指出,你的应用达到了安卓应用构建架构(build architecture)的限制,早期版本中错误信息如下:

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)字节码文件中可饮用的方法总数。如果你在构建一个安卓应用程序的时候遇到了这个错误,祝贺你,你已经有了相当多的代码!这个文档解释了如何越过这个限制从而可以继续构建你的app。

注意:本文的指导继承了来自于安卓开发者的博文Custom Class Loading in Dalvik.


关于65k的引用限制


安卓应用(APK)文件包含着以可执行Dalvik(DEX)文件表示的可执行字节码文件,这个文件中包含着在app中执行的编译代码。DEX的说明中限制在一个DEX文件中可被引用的方法总数不能超过65536,包括安卓框架(framework)的方法,库(library)方法和你自己代码中的方法。如果希望超过这个限制则需要在安卓构建的过程中生成多个DEX文件,我们称之为multidex配置。


Multidex支持安卓5.0以前的系统

安卓5.0以前的系统版本在Dalvik运行的时候执行y应用代码。通常来说,Dalvik限制每个apk文件只有一个classes,dex字节码文件。为了避开这个限制,我们可以使用multidex支持库( multidex support library),它成为了你的app中原生DEX文件的一部分,并且可以管理使用额外的DEX文件以及这些DEX文件包含的代码。


Multidex支持安卓5.0及更高版本的系统

安卓5.0以及更高版本的系统,通过ART可以直接从APK中加载多个DEX文件。ART在应用程序安装的时候会进行预编译,通过扫描所有的classes(...N).dex文件,将他们编译成为一个.oat文件,从而可以在安卓装置中执行。如果想了解更多关于安卓5.0的运行机制,请看 关于ART的介绍


避免65k的限制


在配置你的app支持65k或更多的方法引用之前,你应该采取措施减少代码中的引用总数,包括代码中的方法以及引用的类库中的方法。下面的几个策略能够帮助你们避免dex的引用限制。

审查你的app中直接或间接的依赖-确保任何大型的依赖库在app中的引用要比在程序中添加大量代码更有价值。一个典型的反例就是添加一个很大的依赖库只因为需要使用其中很少的功能。减少代码中的依赖经常可以帮助你避免dex引用限制。

通过混淆器移除未使用的代码-安装混淆器,设置应用执行混淆器,使得app在发布构建的时候能够收缩( shrinking),收缩能够确保未使用的代码不会被装置到APK中。


在Gradle下为你的APP配置Multidex


Gradle的安卓插件在安卓SDK工具(Android SDK Build Tools)21.1及以上版本支持将multidex作为构建配置的一部分。在试图为app安配置multidex之前,请确认你使用SDK Managert更新了安卓SDK构建工具以及安卓支持库到最新版本。
设置你的app开发工程能够使用multidex配置,需要你对工程做一些修改。特别是你需要执行以下步骤:
  • 改变你的Gradle构建配置使得能够支持multidex
  • 修改manifest去引用MultiDexApplication

修改你的app 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'
}

注意:在你的Gradle 构建文件中,你可以指定multiDexEnabled设置在defaultConfig, buildType, 或者productFlavor或者

在manifest中的application元素中增加来自multidex支持库中的MultiDexApplication

<?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>
当我们在app中增加了这些配置,安卓构建工具够早了一个原生的DEX(classes.dex)并且支持(classes2.dex,classes3.dex)等等,构建系统也会将这些信息打包到apk中。

注意:如果app使用了扩展的Application类,你可以覆盖(override)他的attachBaseContext()方法并且调用MultiDex,install(this)从而支持multidex。如需了解更多信息,请参考MultiDexApplication文档。


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值