应用程序方法数超过限制解决办法

Message报错信息:
   
   
  1. Error:Execution failed for task ':little_farmer:transformClassesWithDexForDebug'.
  2. > com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'E:\install\JavaX64\JavaX64\jdk1.7.0_45\bin\java.exe'' finished with non-zero exit value 2

Gradle Console查看到的详细信息:
   
   
  1. UNEXPECTED TOP-LEVEL EXCEPTION:
  2. com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
  3. at com.android.dx.merge.DexMerger$6.updateIndex(DexMerger.java:502)
  4. at com.android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.java:277)
  5. at com.android.dx.merge.DexMerger.mergeMethodIds(DexMerger.java:491)
  6. at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:168)
  7. at com.android.dx.merge.DexMerger.merge(DexMerger.java:189)
  8. at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:502)
  9. at com.android.dx.command.dexer.Main.runMonoDex(Main.java:334)
  10. at com.android.dx.command.dexer.Main.run(Main.java:277)
  11. at com.android.dx.command.dexer.Main.main(Main.java:245)
  12. at com.android.dx.command.Main.main(Main.java:106)

解决办法:
1.导入包
   
   
  1. dependencies {
  2. ...
  3. compile 'com.android.support:multidex:1.0.0'
  4. ...
  5. }
2.添加默认配置
   
   
  1. defaultConfig {
  2. applicationId "项目包名"
  3. minSdkVersion 14
  4. targetSdkVersion 23
  5. compileOptions {
  6. sourceCompatibility JavaVersion.VERSION_1_7
  7. targetCompatibility JavaVersion.VERSION_1_7
  8. }
  9. multiDexEnabled true
  10. }
3.改变Application
1)让MyApplication extends android.support.multidex.MultiDexApplication;
         
2)如果不想继承 android.support.multidex.MultiDexApplication,那么就可以进行如下配置
   
   
  1. @Override
  2. protected void attachBaseContext(Context base) {
  3. super.attachBaseContext(base);
  4. MultiDex.install(this);
  5. }


使用MutiDex注意事项:


一. 如果你继承了MutiDexApplication或者覆写了Application中的attachBaseContext()方法.

Application类中逻辑的注意事项:

Application 中的静态全局变量会比MutiDex instal()方法优先加载,所以建议避免在Application类中使用静态变量引用main classes.dex文件以外dex文件中的类,可以根据如下所示的方式进行修改:

    
    
  1. @Override
  2. public void onCreate() {
  3. super.onCreate();
  4. final Context mContext = this;
  5. new Runnable() {
  6. @Override
  7. public void run() {
  8. // put your logic here!
  9. // use the mContext instead of this here
  10. }
  11. }.run();
  12. }

二. 虽然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的实现则可以很好地解决此问题。


对于dex 的--multi-dex 选项设置与预编译的library工程有冲突,因此如果你的应用中包含引用的lirary工程,需要将预编译设置为false:
   
   
  1. android {
  2. // ...
  3. dexOptions {
  4. preDexLibraries = false
  5. }
  6. }

OutOfMemoryError: Java heap space
当运行时如果看到如下错误
   
   
  1. UNEXPECTED TOP-LEVEL ERROR:
  2. java.lang.OutOfMemoryError: Java heap space
dexOptions 中有一个字段用来增加java堆内存大小:
    
    
  1. android {
  2. // ...
  3. dexOptions {
  4. javaMaxHeapSize "2g"
  5. }
  6. }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值