`
gjhappyyy
  • 浏览: 259549 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

解决Android单个dex文件不能超过65536个方法问题

 
阅读更多

当我们的项目代码过大时,编译运行时会报Unable to execute dex: method ID not in[0, 0xffff]: 65536)错误。当出现这个错误时说明你本身自己的工程代码中含有的太多的方法,或者你的工程lib文件夹下引用的第三方插件jar包有太多的方法,这两者的方法加起来已经超过了65536这个数目。而谷歌规定单个dex文件中的方法不能超过65536的限制。

  那么这个时候,我们就需要分包处理解决。一般情况下的解决方案就是把整个项目工程包括jar,区分开来分解成两个dex文件。

  网上很多这些解决方案,有的把项目代码中比较独立的模块打包成jar文件,然后利用dx工具将打包的jar文件转成dex文件的jar,然后将其放到SD卡中去动态加载。这种方案是不符合我们的需求的。

  那么问题来了,该如何更好的去拆分Dex文件,绕过谷歌规定的65536呢?其实,网上已经有些牛人帮我们提出了很多方案了,尤其是在github上。特别是mmin18提出的方案,githut地址如下:

  https://github.com/mmin18/Dex65536

该解决方案的原理差不多是这样:

  1.在工程目录下创建custom_rules.xml文件,修改编译策略。将工程lib的文件中含有的第三方插件jar包全部打包成libs.apk,然后将其作为编译运行时的第二个dex文件。

  2.最后通过ant命令执行操作,运行整个工程或签名加密打包整个工程。

   怎么样,通过上面的介绍是不是觉得很简单,其实不然,如果要真正的去了解整个原理,还是很有难度,首先你得对custom_rules.xml文件的相关配置和android工程的编译策略非常熟悉。不过,这里我们不用管它,既然牛人已经帮我们写好了,那我们只要知道怎么去用到我们的项目中就行了。

   接下来就是怎么去用到我们的项目代码中了(当然,感兴趣的同志可以去研究研究它的实现原理)。

 

 

一.配置和运行工程步骤如下:

  1. 竟然要用到ant,首先就要先下载ant和配置ant环境,下载链接地址为:http://ant.apache.org/bindownload.cgi。下载好apache-ant-1.9.4-bin.zip包后,解压到指定目录。然后配置环境变量,创建变量名为ANT_HOME,值为ant文件对应的路径,比如我的是ANT_HOME = E:\apache-ant-1.9.4-bin\apache-ant-1.9.4。然后在Path变量的值中追加%ANT_HOME%/bin;%ANT_HOME%/lib。这样ant环境变量就配置好了。

  2. 接下来就是拷贝文件custom_rules.xml和pathtool.jar到我们项目的根目录下。

  3.  然后就在我们的项目运行之前添加代码执行去加载第二个dex文件,下面的dexTool方法就是执行加载第二个dex文件的功能代码,直接copy到我们的自定义application类中就行了,代码如下:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. @SuppressLint("NewApi")  
  2.   privatevoid dexTool() {  
  3.          FiledexDir = new File(getFilesDir(), "dlibs");  
  4.          dexDir.mkdir();  
  5.          FiledexFile = new File(dexDir, "libs.apk");  
  6.          FiledexOpt = getCacheDir();  
  7.          try{  
  8.                 InputStreamins = getAssets().open("libs.apk");  
  9.                 if(dexFile.length() != ins.available()) {  
  10.                        FileOutputStreamfos = new FileOutputStream(dexFile);  
  11.                        byte[]buf = new byte[4096];  
  12.                        intl;  
  13.                        while((l = ins.read(buf)) != -1) {  
  14.                               fos.write(buf,0, l);  
  15.                        }  
  16.                        fos.close();  
  17.                 }  
  18.                 ins.close();  
  19.          }catch (Exception e) {  
  20.                 thrownew RuntimeException(e);  
  21.          }  
  22.    
  23.          ClassLoadercl = getClassLoader();  
  24.          ApplicationInfoai = getApplicationInfo();  
  25.          StringnativeLibraryDir = null;  
  26.          if(Build.VERSION.SDK_INT > 8) {  
  27.                 nativeLibraryDir= ai.nativeLibraryDir;  
  28.          }else {  
  29.                 nativeLibraryDir= "/data/data/" + ai.packageName + "/lib/";  
  30.          }  
  31.          DexClassLoaderdcl = new DexClassLoader(dexFile.getAbsolutePath(),  
  32.                        dexOpt.getAbsolutePath(),nativeLibraryDir, cl.getParent());  
  33.    
  34.          try{  
  35.                 Fieldf = ClassLoader.class.getDeclaredField("parent");  
  36.                 f.setAccessible(true);  
  37.                 f.set(cl,dcl);  
  38.          }catch (Exception e) {  
  39.                 thrownew RuntimeException(e);  
  40.          }  
  41.   }  

 

    接着在自定义application类的onCreate方法中调用dexTool。

  4. 自动生成build.xml文件。打开命令窗口,进入到工程的根目录下,输入如下命令android update project -p .  在输入该命令之前,要确保你配置的sdk/tools目录和sdk/tools/lib文件夹中有android.bat和find_java.bat文件。

  5. 然后就是运行该工程了。输入命令ant clean debug install run,在输入该命令之前要确保你的ant环境配置没有问题。

二.签名混淆代码:

上面的运行apk并没有通过代码混淆和签名,一般情况下我们需要生成一个经过代码混淆和签名的apk,那么ant环境下怎么去配置才能生成代码混淆和签名的apk呢。接下来将进行说明。

     1. 在刚刚已经配置好的工程根目录下创建ant.properties文件,该文件在创建工程时是不会自动生成的,需要我们自己去创建。这个文件会在build.xml文件中声明。

     2. 然后在创建好的ant.properties中添加相关信息,比如我添加的信息如下  

         

         第一行内容为配置关联相关的加密信息文件(也可能为proguard.config = proguard.cfg)

        第二行内容为指定签名文件所在路径,./keystore.eking,说明该签名文件在工程根目录下(拷贝签名文件到工程根目录)

        第三行内容为签名文件的alias值为eking

        第四、第五行分别为签名文件对应的store、alias密码。 

      3.接着在工程目录下执行如下命令antrelease, 执行完后会自动在工程的bin目录下生成appname-release.apk文件,这个就是签名后生成的apk。

 

   Demo下载地址:http://download.csdn.net/detail/stevenhu_223/8184135

   注:该Demo已经通过验证。其中lib/60k-methods.jar有60k个方法,Demo工程中也有60k个方法,但是该Demo可以顺利执行,说明该方案是可行的。

   关于拆分dex文件解决dex 65536有效解决方案的介绍就到此结束。有兴趣的同志还可以去深入研究它的实现原理。

分享到:
评论

相关推荐

    解决Android单个dex文件限制65536个方法问题

    每个DEX文件内部可以包含大量的类和方法,但Android系统对单个DEX文件的方法数量存在一个硬性限制,即不超过65536个。这个限制源于早期的Dalvik虚拟机设计,目的是为了优化内存占用和加载速度。然而,随着应用程序的...

    解决Android单个dex文件不能超过65535个方法的类库

    Dalvik可执行规格限制一个Dex文件包含65536个方法:包括Android框架方法、Library方法的总数、和你自己的代码方法总数。因为65536等于64×1024,这一限制被称为“64k引用限制”。 这个极限就要求我们配置应用程序的...

    Android studio手动创建并生成dex文件源码

    6. **注意问题与优化**:随着应用的增长,单个Dex文件可能会超过64K方法限制,这时需要使用Multi-Dex支持。在Gradle配置中启用multiDexEnabled为true,并引入`com.android.support:multidex:1.0.3`库,确保应用可以...

    动态加载dex动态加解密dex文件

    然而,当应用的类数量超过65536个(Android 5.0之前DEX文件的限制),就需要将代码拆分为多个Dex文件,即MultiDex。在Android 5.0及以上版本,系统内置了对MultiDex的支持,但低于此版本的应用则需要自定义解决方案...

    DEX文件学习笔记

    3. **多DEX支持**:大型应用可能超过单个DEX文件的大小限制(约64K方法),为此,Android引入了multi-DEX支持,允许应用包含多个DEX文件。 4. **安全与签名**:DEX文件在安装前会进行校验,确保未被篡改。同时,APK...

    Dex方法数查看工具

    Android系统早期为了降低设备内存需求,对单个Dex文件中的方法数进行了限制。随着应用复杂度的增加,这个限制逐渐成为开发大型应用的瓶颈。为了解决这个问题,Google引入了Multi-Dex支持,允许一个应用包含多个Dex...

    Dex文件结构

    随着应用规模的扩大,单个Dex文件可能会超过Dalvik/ART的加载限制。为此,Android引入了 multidex 支持,允许APK包含多个Dex文件。主Dex文件(classes.dex)包含大部分常用类,其他Dex文件(如classes2.dex、classes...

    利用dex-method-counts-master查看app方法数量

    在Android 6.0(API级别23)之前,单个DEX文件最多只能包含65536个方法引用,这包括应用自身的方法和依赖库的方法。超过这个限制,应用将无法安装。为了解决这个问题,Google引入了 multidex 功能,允许一个应用包含...

    android打包JAR,DEX

    在Android开发中,打包JAR和DEX文件是两个重要的步骤,它们涉及到应用的构建和运行。JAR(Java Archive)是Java平台上的一个文件格式,用于集合多个类文件和其他资源,便于分发和使用。而DEX(Dalvik Executable)是...

    一键合并指定jar包,一键生成.dex.zip

    每个.dex文件都有一个方法数的上限,即65536个。当应用包含大量库或者模块时,很容易超过这个限制,因此需要对代码进行优化和打包策略调整。 此工具的核心功能是将多个jar包转换为.dex文件。jar包是Java字节码的...

    Android-加快存在多个dex的项目调试时的打包速度

    为了解决这个问题,Android引入了Multi-Dex支持,允许应用程序包含额外的.dex文件,如classes2.dex、classes3.dex等。 **启用Multi-Dex** 在Gradle构建系统中,可以通过以下配置启用多Dex: ```groovy android { ...

    安卓 android dexclassloader 独立dex

    这样做的主要目的是解决65K方法限制问题,这是Dalvik/ART对单个.dex文件内可定义的方法数量的最大限制。超过这个限制的应用将无法正常编译或运行。 在给定的项目“android-custom-class-loading-sample”中,开发者...

    热更新(添加补丁—dex文件).xmind.zip

    - Dex文件的合并:在热更新过程中,可能需要将新版本的Dex文件与旧版本合并,生成一个包含所有版本类的单个Dex文件,或使用Multi-Dex机制处理多个Dex文件。 - Dex优化:为了提高运行效率,Android系统会预先优化...

    安卓多 dex 加载和 dex 加解密

    为了解决这个问题,Android引入了多DEX加载机制,使得大型应用可以分割成多个DEX文件进行加载。本篇文章将深入探讨安卓多DEX加载以及DEX加解密的相关技术。 首先,我们要理解Android的 Dex 文件结构。Dex 文件是...

    Android最大方法数和解决方案1

    Android开发过程中,遇到的一个常见问题是“64K限制”,这是由于Android系统对于单个Dex文件中的方法数目的限制。这个限制源于两个方面:64K限制和LinearAlloc限制。 1.1 64K限制 这个限制源于Android的Dalvik...

    dex-tools-2.1-SNAPSHOT.rar

    这允许一个应用包含多个Dex文件,以解决Dalvik虚拟机对单个Dex文件大小的限制问题。Android Studio和Gradle插件提供了自动处理多Dex文件的机制。 4. **反编译**:反编译是将机器可读的二进制代码转换回人类可读的源...

    安卓反编译dex文件格式实例分析

    与传统的 Java 字节码(.class 文件)不同,dex 文件通过将多个类文件编译合并为单个文件,减少了在移动设备上的重复代码,从而节省存储空间,提高程序的运行效率。 dex 文件格式分析的第一步是准备一个可分析的...

    dex 转 jar 工具

    在实际使用中,开发者可能会遇到一些挑战,比如处理多个DEX文件(由于Dalvik虚拟机对单个DEX文件大小的限制,大型应用可能包含多个DEX),或者需要处理混淆过的代码。在这种情况下,Dex2Jar工具可能需要与其他反编译...

    Android_Apk_Dex_dynamic_load_sourcecode.zip

    2. `dexopt`和`multi-dex`:对于较大的应用,单个Dex文件可能会超过65K方法限制。在这种情况下,需要使用`multi-dex`支持,将Dex文件拆分为主Dex(包含关键类)和其他辅助Dex文件。在动态加载时,需要确保所有辅助...

    dex-method-counts-master.zip

    它可以通过命令行界面运行,可以分析单个DEX文件,或者整个APK中的DEX文件集合。通过这个工具,开发者能够快速了解项目中的方法数量,包括类方法和实例方法,这有助于识别可能需要优化的部分。 使用该工具的步骤...

Global site tag (gtag.js) - Google Analytics