Android: my application is too large and gives “Unable to execute dex: method ID not in [0, 0xffff]: 65536”?

前端 未结 8 1877
慢半拍i
慢半拍i 2020-11-27 04:52

I am trying to integrate my application with Box, Dropbox, and Google Drive. All 3 of these services require a number of 3rd party jars. Additionally, my application alrea

相关标签:
8条回答
  • 2020-11-27 04:53

    ***NEW**** All of the other answers are now outdated. Here's the new fix

    Android 5.0 and higher

    Multi-dex support is included automatically. From the docs:

    Android 5.0 and higher uses a runtime called ART which natively supports loading multiple dex files from application APK files. ART performs pre-compilation at application install time which scans for classes(..N).dex files and compiles them into a single .oat file for execution by the Android device. For more information on the Android 5.0 runtime, see Introducing ART.

    Below Android 5.0

    Simply add the Android mult-dex support tool to your gradle build:

    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'
    }
    
    0 讨论(0)
  • 2020-11-27 04:56

    Here is a script I wrote for counting the number of methods in each jar (and in total) for a specific folder.

    Once you count the methods you can concentrate on refactoring and removing heavy libraries.

    0 讨论(0)
  • 2020-11-27 04:58

    I faced this issue recently. After scouring the web for some more detailed implementation, I realized there wasn't much out there other than:

    • Good but a little outdated now that Gradle is around: http://android-developers.blogspot.co.il/2011/07/custom-class-loading-in-dalvik.html
    • Not much details but a vague idea of how it could be done: https://www.facebook.com/notes/facebook-engineering/under-the-hood-dalvik-patch-for-facebook-for-android/10151345597798920

    I realized that the problem was not necessarily that there were too many methods in my code, but that the full dex of my code and other libraries was the issue. So, if I could compile my code against the libraries but not include them in the classes.dex, and then dex the libraries separately, and then put it all together at runtime it should work. The only issue left to address is the class loader, which Facebook mentioned in passing.

    So with a little reflection and some Groovy code, I think I came up with a relatively stable way to package the libraries and the application code into separate dex files.

    https://gist.github.com/nickcaballero/7045993

    0 讨论(0)
  • 2020-11-27 05:00

    You can also develop one or more of these as a plugin to your main app, in the form of a separate APK available for download. That APK would expose some component that the main app would use -- since I do not know the nature of your integration with these services, I cannot make a more specific recommendation about that. You would use your own signature-level custom <permission> to secure communications between the two apps. And, as a bonus, if using the third-party library adds requirements for additional permissions, you would only need those permissions in the plugin APK, keeping your main APK smaller.

    0 讨论(0)
  • 2020-11-27 05:00

    See vm/LinearAlloc.c and you can find this code: (5MiB under Android 2.3.3, 8MiB after Android 4.0 as my investigation)

    #define DEFAULT_MAX_LENGTH (5*1024*1024)

    ...

    LinearAllocHdr* pHdr;

    ...

    pHdr->mapLength = DEFAULT_MAX_LENGTH;

    I suppose that the 'Facebook fix' is editing this memory by using native C pointer. IMHO LinearAlloc problem and this method ID problem is different thing.

    0 讨论(0)
  • 2020-11-27 05:07

    You need to enable the Dex support for that. So you need to do these steps:

    1. Gradle plugin v0.14.0 for Android adds support for multi-dex. To enable, you just have to declare it in build.gradle:
    android {
       defaultConfig {
          ...
          multiDexEnabled = true
       }
    }
    
    1. if app support > 5.0 (that is, if your minSdkVersion is 20 or below) you also have to dynamically patch the application ClassLoader, so it will be able to load classes from secondary dexes. for that you can add this lib.
     dependencies {
          ...
          compile 'com.android.support:multidex:1.0.0'
        }
    
    1. enable in code for that you have these option. choose one which suits you best

    A. Add MultiDexApplication in manifest manifest

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.multidex.App"> <application
    android:name="android.support.multidex.MultiDexApplication">
    </application>
    </manifest>
    

    B. Extend the application by MultiDexApplication

    public class App extends MultiDexApplication { .. }
    

    C. install it in application in attaching base context.

    public class App {
        protected void attachBaseContext(Context base) {
            super.attachBaseContext(base);
            MultiDex.install(this);
            ..
        }
    
    }
    

    For more go through this link MultiDex.

    0 讨论(0)
提交回复
热议问题