导致DexIndexOverflowException的方法引用列表

时间:2015-10-05 09:05:49

标签: android android-studio android-multidex

我遇到导致com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536的问题。

我知道使用multiDexEnabled,但我不想实施或使用它,因为它有一些限制。

其中一个是:

  

使用multidex的应用程序可能无法在运行的设备上启动   应用程序早于Android 4.0(API级别14)的平台版本   到Dalvik linearAlloc bug(问题22586)。如果您的目标是API   等级早于14,请务必使用这些进行测试   您的应用程序可能遇到问题的平台版本   启动时或加载特定类组时。码   缩小可以减少或可能消除这些潜在的问题。

由Google link

引用

我想知道一种可以向我显示导致此问题的方法引用列表的方法。以便我可以在导入我已经在项目中的库时删除这些模块。

示例:

compile('org.apache.httpcomponents:httpmime:4.3.6') {
        exclude module: 'httpclient'
    }
compile 'org.apache.httpcomponents:httpclient-android:4.3.5'

1 个答案:

答案 0 :(得分:2)

我建议暂时使用multi-dex,然后使用baksmali对生成的dex文件进行带注释的十六进制转储。带注释的十六进制转储将包含方法引用列表。

baksmali -N -D out.dump -e classes.dex myapp.apk
baksmali -N -D out2.dump -e classes2.dex myapp.apk

您想要查找" method_id_item部分"在2个转储文件中。此部分包含dex文件中使用的方法引用的完整列表。它看起来像

                           |-----------------------------
                           |method_id_item section
                           |-----------------------------
                           |
                           |[0] method_id_item
003c38: 0500               |  class_idx = type_id_item[5]: Lafzkl/development/mColorPicker/drawables/AlphaPatternDrawable;
003c3a: b000               |  proto_idx = proto_id_item[176]: (I)V
003c3c: 1900 0000          |  name_idx = string_id_item[25]: <init>
                           |[1] method_id_item
003c40: 0500               |  class_idx = type_id_item[5]: Lafzkl/development/mColorPicker/drawables/AlphaPatternDrawable;
003c42: d500               |  proto_idx = proto_id_item[213]: (Landroid/graphics/Canvas;)V
003c44: df02 0000          |  name_idx = string_id_item[735]: draw
                           |[2] method_id_item
003c48: 0500               |  class_idx = type_id_item[5]: Lafzkl/development/mColorPicker/drawables/AlphaPatternDrawable;
003c4a: a400               |  proto_idx = proto_id_item[164]: ()V
003c4c: 4103 0000          |  name_idx = string_id_item[833]: generatePatternBitmap
                           |[3] method_id_item
003c50: 0500               |  class_idx = type_id_item[5]: Lafzkl/development/mColorPicker/drawables/AlphaPatternDrawable;
003c52: 4500               |  proto_idx = proto_id_item[69]: ()Landroid/graphics/Rect;
003c54: 4e03 0000          |  name_idx = string_id_item[846]: getBounds
                           |[4] method_id_item
003c58: 0500               |  class_idx = type_id_item[5]: Lafzkl/development/mColorPicker/drawables/AlphaPatternDrawable;
003c5a: 0c00               |  proto_idx = proto_id_item[12]: ()I
003c5c: 8403 0000          |  name_idx = string_id_item[900]: getOpacity
...

另一种方法是使用dexlib2编写一个小工具来读取dex文件并打印出方法参考。

public class DumpMethods {
    public static void main(String[] args) throws IOException {
        DexBackedDexFile dexFile = DexFileFactory.loadDexFile(args[0], 15);

        for (int i=0; i<dexFile.getMethodCount(); i++) {
            System.out.println(ReferenceUtil.getMethodDescriptor(new DexBackedMethodReference(dexFile, i)));
        }
    }
}

这将在一个简单的列表中打印出方法引用:

Lafzkl/development/mColorPicker/drawables/AlphaPatternDrawable;-><init>(I)V
Lafzkl/development/mColorPicker/drawables/AlphaPatternDrawable;->draw(Landroid/graphics/Canvas;)V
Lafzkl/development/mColorPicker/drawables/AlphaPatternDrawable;->generatePatternBitmap()V
Lafzkl/development/mColorPicker/drawables/AlphaPatternDrawable;->getBounds()Landroid/graphics/Rect;
Lafzkl/development/mColorPicker/drawables/AlphaPatternDrawable;->getOpacity()I
...