Android 使用 Multidex 解决 65536 方法数越界问题

dex分包方案概述与multidex包的配置使用 参考资料: Android dex分包方案 Android分包MultiDex原理 《Android开发艺术探索》博客中间会涉及到dex文件的反编译,参考博文: dex文件的反编译-dex2jar和jd-gui1.dex分包的原因对于功能越来越复杂的app的两大问题 问题一:当项目越来越大,方法数超过65536,编译时会出错(为什么是65536,参考下面关于dexopt对方法id检索存储介绍 阅读详情

       在 Andorid 中单个 dex 文件所能包含的最大方法数为 65536,这包含 Android FrameWork、依赖的 jar 包以及应用本身的代码中所有的方法,65536 是一个很大的数字,一般来说一个简单的应用很难达到 65536 这个方法数,但是一些比较大型的应用以及大家开始越来越多的使用组件化开发,65536 就很容易达到,当应用的方法达到 65536 后,编译器就无法完成编译,会抛出异常,今天我们就来一起看看如何来解决方法数越界这个问题


一、问题所报异常


我们来看一下当方法数超出以后编译器所报的异常:


UNEXPECTED TOP-LEVEL EXCEPTION:  
java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65536  
at com.android.dx.merge.DexMerger$6.updateIndex(DexMerger.java:501)  
at com.android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.java:282)  
at com.android.dx.merge.DexMerger.mergeMethodIds(DexMerger.java:490)  
at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:167)  
at com.android.dx.merge.DexMerger.merge(DexMerger.java:168)  
at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:189)  
at com.android.dx.command.dexer.Main.runMonoDex(Main.java:454)  
at com.android.dx.command.dexer.Main.run(Main.java:303)  
at com.android.dx.command.dexer.Main.main(Main.java:215)  
at com.android.dx.command.Main.main(Main.java:106) 
       相信大家有过方法数越界问题的对上面所报的错误应该是比较熟悉的,还有一种情况有所不同,有时候方法数并没有达到 65536 并且编译器也正常的完成了编译工作,但是应用在低版本安装时异常中止,异常信息如下:

E/dalvikvm:Optimization failed
E/dexopt failed on '/data/dalvik - cache/data@app@com.ryg.multidextest - 2.apk@classes.dex' res =65280

       为什么会出现这样的情况那,其实是这样的,dexopt 是一个程序,应用在安装时,系统会通过 dexopt 来优化 dex 文件,在优化过程中 dexopt 采用一个固定大小的缓冲区来存储应用中所有的方法信息,这个缓冲区就是 LinearAlloc,LinearAlloc 缓冲区在新版本的 Andriod 系统中,其大小是 8MB 或 16MB,但是在 2.2 和 2.3 中却只有 5MB,当待安装的 apk 中的方法数比较多时,尽管他还没有达到 65536 这个方法数的上限,但是它的存储空间仍然有可能超出 5MB 这种情况下 dexopt 程序就会报错,从而导致安装失败,这种情况主要在 2.X 系统的手机上出现,可以看大不管是编译时方法数越界还是安装时的 dexopt 错误,它们都给开发过程带来很大的困扰


二 、问题如何解决


1)首先我们应该删除无用的代码和第三方库,这是我们首先需要考虑的,但是可能在大多数情况下,即使我们删除了无用的代码和库,方法数仍然越界,之前大家会通过插件化的机制来动态加载部分 dex,通过将一个 dex 拆分成多个 dex,这就在一定程度上解决了方法数越界的问题,但是插件化是一套重量级的方案,并且其兼容性问题较多,从单纯解决方法数越界问题来说,插件化并不是一个非常适合的方案


2)为了解决这个问题,Google 在 2014 年提出 multidex 的解决方案,通过 multidex 可以很好地解决方法数越界的问题,并且使用起来非常简单

在 Android 5.0 以前使用 multidex 需要引入 Google 提供的 android - support - multidex.jar 这个 jar 包,这个 jar 包可以在 Android SDK 目录下的

extras/android/support/multidex/library/libs 下面找到,从 Android 5.0 开始,Android 默认支持了 multidex 它可以从 apk 中加载多个 dex 文件,

Multidex 方法主要是针对Android Studio 和 Gradle 编译环境的,如果是 Eclipse 和 Ant 就会更复杂,而且由于 Android Studio 作为官方 IDE

已经完全替代了 Eclipse ADT,所以我们接下来只介绍 AndroidStudio 如何来配置,就不在介绍 Eclipse 如何配置了


三、在 Andorid Studio 中进行配置


在 Android Studio 和 Gradle 编译环境中,如果要使用 multidex,首先要使用 Andorid SDK Build Tools 21.1 及以上版本,接着修改工程目录中

app 目录下的 build.gradle 文件,在deflautConfig 闭包中添加 multiDexEnabled true 这个配置项,如下所示,如果你对 Andorid Studio 的 Gradle

还不是很了解 可以先阅读如下文章,文章对 build.gradle 做了详细的解答:

Android 详解 build.gradle 文件

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
        applicationId "com.example.qiudengjiao.multidex"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        //在这里添加 multidex support
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
}

接着我们还需要在 dependencies 中添加 multidex 的依赖

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'

    //添加如下multidex依赖
    compile 'com.android.support:multidex:1.0.1'
}

最终完成配置的 build.gradle 文件如下所示:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
        applicationId "com.example.qiudengjiao.multidex"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        //在这里添加 multidex support
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'

    //添加如下multidex依赖
    compile 'com.android.support:multidex:1.0.1'
}

经过上面的过程,还需要在代码中加入支持 multidex 的功能,这个过程是比较简单的,有 3 种方案可选

1)第一种方案


在 AndroidManifest.xml 文件中指定 Application 为 MultiDexApplication 如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.qiudengjiao.multidex">

    <application
        android:name="android.support.multidex.MultiDexApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

2)第二种方案


让应用的 Application 继承 MultiDexApplication 例如:


public class TestApplication extends MultiDexApplication {
    
}

3)第三种方案


      如果不想让应用的 Application 继承 MultiDexApplication,还可以选择重写 Application 的 attachBaseContext 方法,这个方法比 Application 的onCreate 要先执行,如下所示:

public class TestApplication extends Application{
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }
}

       现在所有工作就完成了,可以发现应用不但可以编译通过,还可以在 Andorid 2.x 手机上正常安装,可以发现,multidex 使用起来还是非常方便,对于一个使用 multidex 方案的应用,采用了上面的配置项,如果这个这个方法数没有越界,那么 Gradle 并不会生成多个 dex 文件,如果方法数越界后,Gradle 就会在 apk 中打包 2 个或多个 dex 文件,具体打包多少个 dex 文件要看当前项目的代码规模


简述Android 解决65536/64K方法数限制方案 在Android项目开发中,尤其是开发类似淘宝,京东,微信,直播等大型项目中,由于产品的迭代,业务模块的快速增长,到了一定的规模后难免会遇到65536/64K方法数的问题。它是个什么鬼?这个问题,网上还有其他人说65方法数问题,本质上都市指Android Dalvik可执行文件.dex中的Java方法数引用超过65536,64K的计算方法是65536/1024,65K的计算方法是65536/1000 阅读详情

相关推荐

Android应用中突破65536方法限制的Multidex文件解决方案

为了解决方法数超限的问题,Android引入了Multidex支持。Multidex是指在单个应用中使用多个DEX文件来组织和管理代码。这样,开发者能够突破65K方法的限制,将应用拆分成多个DEX文件。对于复杂的应用,可以有效避免方法数的限制,确保所有需要的类和方法都能够被正确加载和使用。随着Android系统版本的不断更新和新技术的引入,Multidex技术也在不断地适应和进化。例如,Android 7.0引入了Project Treble,旨在隔离硬件抽象层(HAL),简化系统更新过程。

weixin_42575505的博客 1318

求解,android读取AndroidManifest中meta-data值为长数字问题

在AndroidManifest.xml文件中有一个meta-data的值为长数字:             android:name="cg_tencent_ads_banner"             android:value="9079537189894199745" /> 使用常用的方法读取: public static String readMetaDataIntSt

yingjizheng2254的博客 1782

AndroidKiller小插件,多dex转java源码,无需关闭编译器直接打开即可看

AndroidKiller小插件,多dex转java源码,无需重启AndroidKiller直接打开jdgui即可看代码,无需手动反编译dex2,3,4,5,省时省力。 ps: 这是解决多dex编译源码的小工具,需要解决编译卡死的,请看我另一个帖子“AndroidKiller_v1.3.1修复高版本dex2jar卡死问题,并更新最新dex2jar和apktool.jar插件”

Android 使用android-support-multidex解决Dex超出方法数的限制问题,让你的应用不再爆棚

随着应用不断迭代,业务线的扩展,应用越来越大(比如集成了各种第三方sdk或者公共支持的jar包,项目耦合性高,重复作用的类越来越多),相信很多人都遇到过如下的错误: UNEXPECTED TOP-LEVEL EXCEPTION: java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65536 没错,你的应用中的Dex 文件方法数超过了最大值65536的上限,简单来说,应用爆棚了. 那么让我们看一下为什么会引起这种

Whatever is worth doing is worth doing well. 19万+

Android中拆包技术

Android中拆包技术详解

Allegro网表导入报错VOIDs not allowed in parent SHAPE的解决方案

在PCB设计流程中,网表导入是确保电气连接正确传递的关键步骤。其原理是将原理图的逻辑连接关系映射到物理版图的图形数据库中。这一过程的技术价值在于保证设计数据的一致性,避免后续生产中出现电气错误。然而,在Cadence Allegro等EDA工具的实际应用中,数据库内部状态的不一致可能引发操作失败,例如常见的“VOIDs are not allowed in the parent SHAPE”报错。这类问题通常源于多人协作、跨版本操作或频繁编辑后积累的数据结构冗余。针对此场景,核心的解决方法是执行Databa

weixin_30954817的博客 322

Android使用multidex解决方法数越界问题65536

概述:在Android中单个dex文件能包含的最大方法数为 65536 。 这个方法数目来自,Android FrameWork,一依赖包,已经代码中包含的方法,还有些项目使用的第三方库里面的方法 的总和。乍一看这个数字很大,一般不会超过。但是随着App的更新速度火箭般提高,和用户的各种需求大量增加,最终在产品汪的指挥下,项目越来越大。现如今,只要是比较大型的项目,都会遇到 65536 问题。问题描

路漫漫亦无涯 3418

Vivado Schematic视图实战:从RTL分析到布局布线,如何用它快速定位设计问题(附2019.1版操作)

本文深入解析Vivado Schematic视图在FPGA设计中的关键作用,从RTL分析到布局布线全流程,帮助工程师快速定位设计问题。通过三重视图对比、高效调试四步法和高级技巧,提升问题排查效率,缩短调试时间。文章结合2019.1版操作指南和实战案例,展示如何利用Schematic视图解决典型设计问题。

weixin_30591551的博客 488

安卓使用 multidex解决方法数越界问题65536

概述: 在Android中单个dex文件能包含的最大方法数为 65536 。 这个方法数目来自,Android FrameWork,一依赖包,已经代码中包含的方法,还有些项目使用的第三方库里面的方法 的总和。 乍一看这个数字很大,一般不会超过。但是随着App的更新速度火箭般提高,和用户的各种需求大量增加,最终在产品的指挥下,项目越来越大。现如今,只要是比较大型的项目,都会遇到 65536 问题

JiaoJunfeng 773

TI C2000 DSP CLA实战:用F28069的协处理器实现ADC采样与PWM相位实时联动控制

本文详细介绍了如何利用TI C2000系列DSP的CLA协处理器在TMS320F28069上实现ADC采样与PWM相位的实时联动控制。通过CLA的零周期上下文切换和硬件级任务触发特性,显著提升了电机控制和数字电源应用的实时性能,特别适用于需要亚微秒级响应的场景。

weixin_30932215的博客 3968

四旋翼黑科技揭秘:如何利用PX4隐藏的角加速度数据提升控制性能

本文深入探讨了如何利用PX4飞控中隐藏的角加速度数据,结合增量非线性动态逆(INDI)控制方法,显著提升四旋翼无人机的控制性能。通过实战教程,指导开发者从数据订阅、INDI原理到代码实现,构建响应更快、鲁棒性更强的控制回路,有效应对突风与快速机动。

lake5的博客 720

AndroidStudio利用android-support-multidex解决65536问题64k问题

当你的应用程序和库引用达到一定规模,你遇到构建错误显示你的应用已经达到了一个Android应用程序构建体系结构的限制。上面的错误显示一个共同的数字:65536。这个数字是重要的,它代表了引用的总数,可以在单个调用的代码Dalvik可执行(Dex)字节码文件。如果你的Android应用发生这个错误,恭喜你,你的代码已经达到了一定的量!本文解释了如何解决这个限制并继续构建应用程序。

布莱克‌ 2万+

Vectorless dynamic动态功耗分析——Voltus

power 计算工具会根据设计信息和用户提供的activity和switching约束来生成虚拟的worst-case的power vector,难点在于哪些instances视为switching,在没有仿真的前提下如何确定开关的时间,使用timing文件(TWF)

qq_44347276的博客 2790

关于方法数越界的那些事

关于方法数越界的那些事 一、方法数越界问题   在Android中单个dex文件所能包含的最大方法数为65536,其中包含Android FrameWork、依赖的jar包以及应用本身的代码中的所有方法。一般来说一个简单应用的方法数很难达到65536,但是对于一些比较大型的应用来说,65536就很容易达到。   当应用方法数达到65536后,编译器就无法完成编译工作并抛出类似下面的异常。 com.android.dex.DexIndexOverflowException:method ID not in [

weixin_38196407的博客 459

机器学习特征选择-t检验

在特征选择的过程中通过计算检验统计量值,比较特征之间的统计量的大小,并降序排列,选取统计值较高的特征,从而起到去除差别小的特征(此差别小的特征难以区分不同的额类别)的目的。 以t检验(Student's t test)为例: 假设检验 通过比较两类样本的随机变化,通过计算其p值决定是否拒绝零假设,也即是说:通过计算p值,若p值小于某一阈值则认为两个样本具有显著差异,两个样本是不同的,此时拒绝...

heda3的博客 6700

TDS水质检测传感器原理图设计,已量产(液体传感器)

最近调试了一款针对生活用水、水培系统的 TDS 水质检测模块 —— 毕竟 TDS(总溶解固体)值直接关联水的洁净程度,是这类场景里既实用又易获取的水质指标。下面拆解下这个电路的设计逻辑,说说每个部分是怎么配合实现精准检测的。

不脱发的程序猿 1541

android MultiDex multidex原理下超出方法数的限制问题(三)

android MultiDex 原理下超出方法数的限制问题(三)  multidex?Android分包MultiDex原理详解?插件化?自动化?multiDex?是不是觉得已经懵逼了?请先看这篇文章的内容,在下篇文章中将会详解具体的过程… 随着应用不断迭代,业务线的扩展,应用越来越大(比如集成了各种第三方sdk或者公共支持的jar包,项目耦合性高,重复作用的类越来越多),相信很多人都遇到过如下的错误: dujinyang UNEXPECTED

奥特曼超人的博客专栏 2万+

机器学习笔记 - 基于深度学习(HomographyNet)的图像单应性估计

论文提出了一个深度卷积神经网络来估计一对图像之间的相对单应性。我们的前馈网络有10层,以两个堆叠的灰度图像作为输入,并产生一个8自由度的单应性,可用于映射从第一个图像到第二个图像的像素。我们为HomographyNet提出了两种卷积神经网络架构一个直接估计实值单应性参数的回归网络,以及一个在量化单应性上产生分布的分类网络。我们使用4点单应性参数化,将一个图像的四个角映射到第二个图像。我们的网络使用扭曲的MS-COCO图像以端到端的方式进行训练。论文的贡献如下。........................

学以致用 知行合一 3083

Android开发——解决方法数越界问题

0. 前言单个DEX文件能够包含的最大方法总数为65536。通常APK包含一个classes.dex文件,因此Android应用的方法总数不能超过这个数量,这包括Android框架、第三方类库和你自己开发的代码。通常开发者自己的代码很难达到这样的方法数量限制,但随着第三方类库的加入,方法数就会迅速膨胀。也许有一天,这个错误就会找上门来:com.android.dex.DexIndexOverFlo...

关于Android开发的一些技术点总结 ╮( ̄▽ ̄”)╭ 1233

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

简单处理Android 65536方法越界问题

看到这篇文章相信大家都是遇到了这个问题的人,对,Android著名的方法65536越界问题,是什么原因造成的呢? 这是因为在Android的单个dex文件中所能包含的最大方法数为65536,这个包含了Android FrameWork 、依赖jar包积极应用本身的代码中的所有方法;当我们的方法数总量达到了65536的话,编译器就会抛出类似下面的异常: Information:Gradle tas

RayXiong的博客 1685

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

multidex解决方法数越界

Android单个dex文件所能包含的最大方法数是65536,这个包括Android FrameWork、依赖jar包以及应用本身的所有方法。当应用的方法数达到65536之后,编译出现问题。 UNEXPECTED TOP-LEVEL EXCEPTION: java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 6

JoneRen的博客 534

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Android工程中方法数超过65536解决方法

Android工程中方法数超过65536解决方法 1 “64k引用限制” 随着APP的不断迭代,自身代码在不断增加,同时项目中由于使用了不少的三方库,这时候方法数超过了65536,带来的后果就是编译和打包失败。 当方法数超过65536的时候,会报如下的错误: The number of method references in a .dex file cannot exceed 64K. Caused by: com.android.tools.r8.utils.AbortException: Error:

xingyu19911016的博客 2919

Android分包方案multidex

对于功能越来越复杂的app的两大问题 一:我们自己应用的方法数超过了65536  我们所说的方法数限制,这个方法数包括了jar包,框架,还有我们自己应用的代码,当我们应用的代码超过65536时,结果如下: 我们看到,显示我们方法的引用是65579.而引用数最大是65536,建议我们开启分包方案。 二:我们应用的方法数没有超过65536,但是加上依赖的jar包,框架等,超过了6...

Tongseng‘s Blog 2283

解决方法数越界的问题

在Android中单个dex文件所能包含的最大方法数是65536,这包含AndroidFrameWork、依赖的jar包以及应用本身的代码所包含的方法。一般来说,一个简单的应用的方法数很难达到65536,但对于一些大型项目来说,就很容易达到了。当应用的方法数达到65536时,编译器就无法完成编译工作并抛出DexIndexOverflowException异常。 还有一种情况,有时候方法数并未达到6...

zss_hhh_oaa_unn的博客 291

Android MultiDex使用

一、MultiDex出现原因: 下段摘自http://www.cnblogs.com/CharlesGrant/p/5112597.html 当Android系统安装一个应用的时候,有一步是对Dex进行优化,这个过程有一个专门的工具来处理,叫DexOpt。DexOpt的执行过程是在第一次加载Dex文件的时候执行的。这个过程会生成一个ODEX文件,即Optimised Dex。执行ODe

lan_学习分享 876
上一篇: Realm for Android 使用入门
下一篇: Android 使用 CrashHandler 来获取应用的 crash 信息
QDJdeveloper
博客等级 码龄11年 108粉丝 49原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值