Search code examples
androidandroid-studioandroid-multidex

list of method references which are causing DexIndexOverflowException


I am facing a problem which is causing com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536.

I know the use of multiDexEnabled but i don't want to implement or use it as it has some Limitations.

One of it is :

Applications that use multidex may not start on devices that run versions of the platform earlier than Android 4.0 (API level 14) due to a Dalvik linearAlloc bug (Issue 22586). If you are targeting API levels earlier than 14, make sure to perform testing with these versions of the platform as your application can have issues at startup or when particular groups of classes are loaded. Code shrinking can reduce or possibly eliminate these potential issues.

referenced by Google link

I want to know a way that can show me the list of method references which are causing this issue. so that i can remove such modules while importing the library which i have already in my project.

Example :

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

Solution

  • I would recommend using multi-dex temporarily, and then use baksmali to do an annotated hex dump of the resulting dex files. The annotated hex dump will include the method reference list.

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

    You'll want to look for "method_id_item section" in the 2 dump files. This section has the full list of method references used in the dex file. It will look something like

                               |-----------------------------
                               |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
    ...
    

    An alternate approach would be to write a little tool using dexlib2 to read the dex file and print out the method refereneces.

    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)));
            }
        }
    }
    

    This will print out the method references in a simple list:

    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
    ...