Android65K

Android65K
随着应用不断迭代,业务线的扩展,应用越来越大(比如集成了各种第三方sdk或者公共支持的jar包,项目耦合性高,重复作用的类越来越多),相信很多人都遇到过如下的错误:
  print?
  1. <span style="color:#ff0000;">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)  </span>  

这个错误的原因是你的app中方法总数超过了65535个。应用被撑爆了。。
那么让我们看一下为什么会引起这种错误:
        在 Android 系统中,一个 App 的所有代码都在一个 Dex 文件里面。 Dex 是一个类似Jar的存储了多有 Java 编译字节码的归档文件。因为 android 系统使用 Dalvik 虚拟机,所以需要把使用 Java  Compiler 编译之后的 class 文件转换成 Dalvik 能够执行的 class 文件。这里需要强调的是, Dex Jar 一样是一个归档文件,里面仍然是 Java 代码对应的字节码文件。当 Android 系统启动一个应用的时候,有一步是对 Dex 进行优化,这个过程有一个专门的工具来处理,叫 DexOpt DexOpt 的执行过程是在第一次加载Dex文件的时候执行的。这个过程会生成一个 ODEX 文件,即 Optimised Dex 。执行 ODex 的效率会比直接执行 Dex 文件的效率要高很多。  但是在早期的Android系统中, DexOpt 的LinearAlloc存在着限制: Android 2.2和2.3的缓冲区只有5MB,Android 4.x提高到了8MB或16MB。当方法数量过多导致超出缓冲区大小时,会造成dexopt崩溃,导致无法安装. 
        另外由于DEX文件格式限制,一个DEX文件中method个数采用使用原生类型short来索引文件中的方法,也就是4个字节共计最多表达65536个method,field/class的个数也均有此限制。对于DEX文件,则是将工程所需全部class文件合并且压缩到一个DEX文件期间,也就是Android打包的DEX过程中, 单个DEX文件可被引用的方法总数被限制为65536(自己开发以及所引用的Android Framework和第三方类库的代码).

在API 21中,Google提供了通用的解决方案。那就是 android-support-multidex.jar . 这个jar包最低可以支持到 API 4 的版本( Android L 及以上版本会默认支持 mutidex ).
这个问题可以通过将一个DEX文件分拆成多个DEX文件解决

首先使用Android SDK Manager升级到最新的Android SDK Build Tools和Android Support Library R21。然后进行以下两步操作:
1.修改Gradle配置文件,启用MultiDex并包含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' }
2.让应用支持多DEX文件。在 MultiDexApplication JavaDoc 中描述了三种可选方法:
  • 在AndroidManifest.xml的application中声明android.support.multidex.MultiDexApplication;
  • 如果你已经有自己的Application类,让其继承MultiDexApplication;
  • 如果你的Application类已经继承自其它类,你不想/能修改它,那么可以重写attachBaseContext()方法:
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this);}

 使用MutiDex的主意事项
一. 如果你继承了MutiDexApplication或者覆写了Application中的attachBaseContext()方法.
Application类中逻辑的注意事项 :
Application  中的静态全局变量会比 MutiDex  instal() 方法优先加载,所以建议避免在 Application 类中使用静态变量引用 main classes.dex 文件以外dex文件中的类,可以根据如下所示的方式进行修改:  
  1. @Override  
  2.     public void onCreate() {  
  3.         super.onCreate();  
  4.   
  5.         final Context mContext = this;  
  6.         new Runnable() {  
  7.   
  8.             @Override  
  9.             public void run() {  
  10.                 // put your logic here!  
  11.                 // use the mContext instead of this here  
  12.             }  
  13.         }.run();  
  14.     }  
二.  虽然Google解决了应用总方法数限制的问题,但并不意味着开发者可以任意扩大项目规模。Multidex仍有一些限制:
  1. DEX文件安装到设备的过程非常复杂,如果第二个DEX文件太大,可能导致应用无响应。此时应该使用ProGuard减小DEX文件的大小。
  2. 由于Dalvik linearAlloc的Bug,应用可能无法在Android 4.0之前的版本启动,如果你的应用要支持这些版本就要多执行测试。
  3. 同样因为Dalvik linearAlloc的限制,如果请求大量内存可能导致崩溃。Dalvik linearAlloc是一个固定大小的缓冲区。在应用的安装过程中,系统会运行一个名为dexopt的程序为该应用在当前机型中运行做准备。dexopt使用LinearAlloc来存储应用的方法信息。Android 2.2和2.3的缓冲区只有5MB,Android 4.x提高到了8MB或16MB。当方法数量过多导致超出缓冲区大小时,会造成dexopt崩溃。
  4. Multidex构建工具还不支持指定哪些类必须包含在首个DEX文件中,因此可能会导致某些类库(例如某个类库需要从原生代码访问Java代码)无法使用。
避免应用过大、方法过多仍然是Android开发者要注意的问题。Mihai Parparita的开源项目dex-method-counts可以用于统计APK中每个包的方法数量。
通常开发者自己的代码很难达到这样的方法数量限制,但随着第三方类库的加入,方法数就会迅速膨胀。因此选择合适的类库对Android开发者来说尤为重要。
开发者应该避免使用Google Guava这样的类库,它包含了13000多个方法。尽量使用专为移动应用设计的Lite/Android版本类库,或者使用小类库替换大类库,例如用Google-gson替换Jackson JSON。而对于Google Protocol Buffers这样的数据交换格式,其标准实现会自动生成大量的方法。采用Square Wire的实现则可以很好地解决此问题。



附:在我见过的项目中引用 multidex的方法:

最后我给大家贴上一个不常见但以后会遇到的错:
这是因为java的堆内存大小被。。撑爆了。所以增加一个字段改变堆内存的大小。
在dexOptions中有一个字段用来增加java堆内存大小:  
  1. android {  
  2.     // ...  
  3.     dexOptions {  
  4.         javaMaxHeapSize "2g"   //大小可以自己设置。
  5.     }  
  6. }    

  


studio中获取代码行数的方法:
1)按住Ctrl+Shift+A,在弹出的框输入‘find’,然后选择Find in Path.(或者使用快捷键Ctrl+Shift+F)
 
       
image
2)在弹出Find in Path的框中的Text to find输入\n,接着勾选Regular expression(正则表达式),Context选择anywhere,
Scope根据你想要统计的范围进行选择,File mask选择*.java。(在这里统计项目的Java的代码行数)
image
3)下图的Useages in generated code是自动生成的代码,上面那个就是项目的代码行数。
image

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.m或d论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 、1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值