zoukankan      html  css  js  c++  java
  • Android 使用android-support-multidex解决Dex超出方法数的限制问题

       随着应用不断迭代,业务线的扩展,应用越来越大(比如集成了各种第三方sdk或者公共支持的jar包,项目耦合性高,重复作用的类越来越多),相信很多人都遇到过如下的错误:

    1. UNEXPECTED TOP-LEVEL EXCEPTION:  
    2. java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65536  
    3. at com.android.dx.merge.DexMerger$6.updateIndex(DexMerger.java:501)  
    4. at com.android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.java:282)  
    5. at com.android.dx.merge.DexMerger.mergeMethodIds(DexMerger.java:490)  
    6. at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:167)  
    7. at com.android.dx.merge.DexMerger.merge(DexMerger.java:188)  
    8. at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:439)  
    9. at com.android.dx.command.dexer.Main.runMonoDex(Main.java:287)  
    10. at com.android.dx.command.dexer.Main.run(Main.java:230)  
    11. at com.android.dx.command.dexer.Main.main(Main.java:199)  
    12. at com.android.dx.command.Main.main(Main.java:103)  

      没错,你的应用中的Dex 文件方法数超过了最大值65536的上限,简单来说,应用爆棚了.

      在Android系统中,一个App的所有代码都在一个Dex文件里面。Dex是一个类似Jar的存储了多有Java编译字节码的归档文件。因为Android系统使用Dalvik虚拟机,所以需要把使用Java Compiler编译之后的class文件转换成Dalvik能够执行的class文件。这里需要强调的是,DexJar一样是一个归档文件,里面仍然是Java代码对应的字节码文件。当Android系统启动一个应用的时候,有一步是对Dex进行优化,这个过程有一个专门的工具来处理,叫DexOptDexOpt的执行过程是在第一次加载Dex文件的时候执行的。这个过程会生成一个ODEX文件,即Optimised Dex。执行ODex的效率会比直接执行Dex文件的效率要高很多。  但是在早期的Android系统中,DexOpt的LinearAlloc存在着限制: Android 2.2和2.3的缓冲区只有5MB,Android 4.x提高到了8MB或16MB。当方法数量过多导致超出缓冲区大小时,会造成dexopt崩溃,导致无法安装. 

        当然,Google看来也意识到了目前应用方法数爆棚的问题, 目前在已经在API 21中提供了通用的解决方案,那就是android-support-multidex.jar. 这个jar包最低可以支持到API 4的版本(Android L及以上版本会默认支持mutidex).

      具体集成:
    将如下配置加入工程 build.gradle

    1. android {  
    2.     defaultConfig {  
    3.         // Enabling multidex support.  
    4.         multiDexEnabled true  
    5.     }  
    6. }  
    7. dependencies {  compile 'com.google.android:multidex:0.1'}  

    接下来集成有两个步骤:

    一. 从sdkextrasandroidsupportmultidexlibrarylibs 目录将android-support-multidex.jar导入工程中

    二. 如果你的工程中已经含有Application类,那么让它继承android.support.multidex.MultiDexApplication类,

         如果你的Application已经继承了其他类并且不想做改动,那么还有另外一种使用方式,覆写attachBaseContext()方法:

    1. public class MyApplication extends MultiDexApplication
      {  
    2.     @Override  
    3.     protected void attachBaseContext(Context base) {  
    4.         super.attachBaseContext(base);  
    5.         MultiDex.install(this);  
    6.     }  

    最后给出build.gradle中的完整配置:

    1. android {  
    2.     compileSdkVersion 21  
    3.     buildToolsVersion "21.1.0"  
    4.   
    5.     defaultConfig {  
    6.         ...  
    7.         minSdkVersion 14  
    8.         targetSdkVersion 21  
    9.         ...  
    10.   
    11.         // Enabling multidex support.  
    12.         multiDexEnabled true  
    13.     }  
    14.     ...  
    15. }  
    16.   
    17. dependencies {  
    18.   compile 'com.android.support:multidex:1.0.0'  
    19. build.gradle 里面的android放

    20.   packagingOptions {
      exclude 'META-INF/NOTICE.txt'
      }

  • 相关阅读:
    【转】SqlServer Text类型字段超过8000字处理
    uniapp项目运行时一直发http://localhost:8080/sockjs-node/info?t=1462183700002请求
    【转】chrome 浏览器调用 ocx 插件
    【转】javascript检测浏览器插件
    【转】web错误代码ERR_BLOCKED_BY_RESPONSE
    我是如何将Sublime Text 4 设置成中文版
    【转】用好 Vue 中 v-for 循环的 7 种方法
    【转】JavaScript console.log %c %o %s %d %f
    [JavaScript]UMD模块
    leetcode-课程表I和课程表II
  • 原文地址:https://www.cnblogs.com/zhaoleigege/p/5188723.html
Copyright © 2011-2022 走看看