Android uses Android-support-multidex to solve the problem of Dex exceeding the number of methods, so that your app is no longer bursting

Source: Internet
Author: User
Tags google guava

if reproduced, please declare the source: Time of the Sand: http://blog.csdn.net/t12x3456 (from the sands of the CSDN blog)

as applications continue to iterate, lines of business expand, applications are growing (for example, by integrating a variety of third-party SDKs or publicly-supported jar packages, with high project coupling and repetitive classes), it is believed that many people have encountered errors such as the following:

Unexpected top-level EXCEPTION:java.lang.IllegalArgumentException:method ID not in [0, 0xFFFF]: 65536at Com.android.dx.merge.dexmerger$6.updateindex (dexmerger.java:501) at com.android.dx.merge.dexmerger$ Idmerger.mergesorted (dexmerger.java:282) at Com.android.dx.merge.DexMerger.mergeMethodIds (dexmerger.java:490) at Com.android.dx.merge.DexMerger.mergeDexes (dexmerger.java:167) at Com.android.dx.merge.DexMerger.merge ( dexmerger.java:188) at Com.android.dx.command.dexer.Main.mergeLibraryDexBuffers (main.java:439) at Com.android.dx.command.dexer.Main.runMonoDex (main.java:287) at Com.android.dx.command.dexer.Main.run (Main.java : @ com.android.dx.command.dexer.Main.main (main.java:199) at Com.android.dx.command.Main.main (main.java:103)

That's right. The number of Dex file methods in your app exceeds the maximum limit of 65536, so simply put, the app is bursting.

So let's see why this error is caused:

In the Android system. All the code for an App is inside a Dex file. Dex is a similar jar of archive files that store many Java -compiled bytecode.

Since the Android system uses the Dalvik virtual machine, you need to convert the class file that was compiled with Java Compiler to Dalvik A class file that can be run.

What needs to be stressed here is. Dex , like the Jar , is an archive file that is still the corresponding bytecode file for the Java code.

When the Android system launches an application, one step is to optimize for Dex , a process that has a dedicated tool to handle. Called dexopt.

The dexopt process runs when the Dex file is first loaded.

This process generates a ODEX file, which is optimised Dex.  Running ODex is much more efficient than running the Dex file directly. However, in the early Android system,dexopt 's linearalloc had limitations: Android 2.2 and 2.3 buffers were only 5MB. Android 4.x has been raised to 8MB or 16MB.

When the number of methods exceeds the buffer size, dexopt crashes, causing the installation to fail.

Additionally due to the Dex file format limitations. The method number in a Dex file is indexed by using the primitive type short to index the file, which means that the maximum number of 65,536 Method,field/class is also limited. For the Dex file, it is the time that all the class files required by project are combined and compressed into one Dex file, which is the Dex process that Android packs. The total number of methods that a single DEX file can be referenced is limited to 65536 (its own development and the code of the referenced Android framework and third-party class libraries).

Now more frequently used methods: (1) application of plug-in, for example, I am participating in the development of the plug-in framework: https://github.com/singwhatiwanna/dynamic-load-apk, if there are suggestions or related issues, welcome to actively participate on Github. (2) Cutting Dex, multiple project: Compile a jar file with the required. class file or a jar file together with some source code. Then use the DX tool provided with the Android SDK to turn the jar file into a dex file.

(can refer to facebook:https://www.facebook.com/notes/facebook-engineering/ under-the-hood-dalvik-patch-for-facebook-for-android/10151345597798920, this inside can also see dynamically changing the Linearalloc buffer on 2.3 The two methods do not conflict, plug-in In addition to solve the application bursting. There are many other strengths that can be seen in my previous articles and not repeated.

Of course,Google also seems to be aware of the problem of the number of application methods now, now in the API has provided a common solution. That's Android-support-multidex.jar. This jar package has the lowest support for API 4 version number (Android L and the above version number will default to support Mutidex).

let's see how to apply Android-support-multidex.jar (The following are examples of use in Anroid Studio, where you need to install the Gradle plugin to use Eclipse development.) Other basically the same ):


can be resolved first with--multi-dex configuration (build.gradle), the generated apk will include multiple Dex files, such as Classes.dex, Classes2.dex. Changes to Build.gradle are required:
afterevaluate {    tasks.matching {        it.name.startsWith (' dex ')    }.each {dx-and        if ( Dx.additionalparameters = = null) {            dx.additionalparameters = []        }        dx.additionalparameters + = '--multi-dex '//Enable Multidex        //optional        //Dx.additionalparameters + = "--main-dex-list= $projectDir/<filename>" . toString ()//enable the Main-dex-list    }}



However, the default Dalvik class loader will only look for classes.dex, so they need to be merged to be recognized

Of course. Now with the support of Android.support.multidex.jar, everything will become very easy, first we look at the relevant source code folder, detailed analysis of the principle I will explain in the following article:
android/support/multidex/buildconfig.classandroid/support/multidex/multidex$v14.classandroid/support/multidex/ Multidex$v19.classandroid/support/multidex/multidex$v4.classandroid/support/multidex/multidex.classandroid/ support/multidex/multidexapplication.classandroid/support/multidex/multidexextractor$1.classandroid/support/ multidex/multidexextractor.classandroid/support/multidex/ziputil$centraldirectory.classandroid/support/ Multidex/ziputil.class

Detailed Integration:
Add a configuration such as the following to project Build.gradleIn
Android {    Defaultconfig {        //enabling Multidex support.        multidexenabled true    }}dependencies {  compile ' com.google.android:multidex:0.1 '}


Multidex Implementation principle:

APK is running at the time. There is a dexpathlist, and Multidex source code, will be based on your system version number of Dexpathlist to make changes. Add all of the Dex to the dexpathlist.



The next integration has two steps:

I. Import Android-support-multidex.jar from the Sdk\extras\android\support\multidex\library\libs folder into project

Two. Assuming that your project already contains the application class, let it inherit the Android.support.multidex.MultiDexApplication class,

Assuming that your application has inherited other classes and does not want to make changes, then there is a second way to overwrite the Attachbasecontext () method:



public class MyApplication extends Fooapplication {    @Override    protected void Attachbasecontext (Context base) { C5/>super.attachbasecontext (base);        Multidex.install (this);}    }


Finally, the complete configuration in Build.gradle is given:

Android {    compilesdkversion    buildtoolsversion "21.1.0"    defaultconfig {        ...        Minsdkversion        targetsdkversion ...        enabling Multidex support.        multidexenabled true    }    ...} dependencies {  compile ' com.android.support:multidex:1.0.0 '}





Things to do with Mutidex's ideas


Suppose you inherit the mutidexapplication or overwrite the Attachbasecontext () method in application.

Considerations for logic in the application class :

Static global variables in application are loaded more than the mutidex instal () method, so it is recommended to avoid using static variable references in the application class The class in the Dex file outside of the main classes.dex file. Can be changed in a way that looks like this:

@Override public    void OnCreate () {        super.oncreate ();        Final Context mcontext = this;        New Runnable () {            @Override public            void Run () {                //Put your logic here!                Use the Mcontext instead of this here            }        }.run ();    }

Two. Although Google overcomes the problem of applying the total number of methods, it does not mean that developers are free to scale up the project.

Multidex still have some limitations:

    1. The process of installing a Dex file into a device is complex. Suppose the second Dex file is too large to cause the app to be unresponsive. You should use Proguard to reduce the size of the Dex file.
    2. Due to a bug in the Dalvik Linearalloc, the app may not start up before Android 4.0 version number. Let's say your app needs to run tests to support these version numbers.

    3. Same due to Dalvik linearalloc limitations. Suppose a large amount of memory is requested may cause a crash.

      Dalvik Linearalloc is a fixed-size buffer. During the installation of the app. The system will run a program named Dexopt to prepare the app for running in the current model. Dexopt uses Linearalloc to store the application's method information.

      The Android 2.2 and 2.3 buffers are only 5MB. Android 4.x has been raised to 8MB or 16MB.

      When the number of methods is excessive, the buffer size is exceeded. can cause dexopt to collapse.

    4. The Multidex build tool also does not support specifying which classes must be included in the first Dex file, so it is possible that some class libraries (such as a class library need to access Java code from native code) cannot be used.

Avoiding excessive application and too many methods is still an issue for Android developers to pay attention to. Mihai Parparita's Open source project dex-method-counts can be used to count the number of methods for each package in the APK.

The developer's own code is often very difficult to reach the limit of this scenario. However, with the addition of third-party class libraries, the number of methods expands rapidly. So choosing the right class library is especially important for Android developers.

Developers should avoid using Google Guava this kind of library. It consists of more than 13,000 methods.

Try to use the Lite/android version number class library designed for mobile apps. or replace the large class library with a small class library, such as replacing the Jackson JSON with Google-gson.

And for Google Protocol buffers this data interchange format. Its standard implementation will generate a large number of methods on its own initiative. The implementation of square wire is a good solution to this problem.


Problems


dexexception:library dex files is not supported in Multi-dex mode, you may see errors such as the following:


Error:execution failed for task ': App:dexdebug ' .> com.android.ide.common.internal.LoggedErrorException:Failed to Run command:    $ANDROID _sdk/build-tools/android-4.4w/dx--dex--num-threads=4--multi-dex    ...  Error Code:    2  Output:    unexpected top-level EXCEPTION:    com.android.dex.DexException:Library Dex Files is not supported in Multi-dex mode at        Com.android.dx.command.dexer.Main.runMultiDex (main.java:322)        at Com.android.dx.command.dexer.Main.run (main.java:228) at        Com.android.dx.command.dexer.Main.main (Main.java : 199) at        Com.android.dx.command.Main.main (main.java:103)


the--multi-dex option setting for Dex conflicts with precompiled Libraryproject, so assuming that your app includes a referenced liraryproject, you need to set the precompilation to false:
Android {    //...    dexoptions {        predexlibraries = False    }}



Outofmemoryerror:java Heap Space

When the runtime assumes that you see an example of the following error:
Unexpected top-level ERROR:java.lang.OutOfMemoryError:Java heap space

In dexoptionsHas a field to add the Java heap memory size:
Android {    //...    dexoptions {        javamaxheapsize "2g"    }}            

Developers who use Eclipse are able to take a Google Official document

Https://developer.android.com/tools/building/multidex.html#mdex-gradle

You need to install a plugin that supports Gradle build:

Http://dist.springsource.com/release/TOOLS/gradle (Fq may be needed right now)



Related information:

1. Mutidex Official document : https://developer.android.com/reference/android/support/multidex/MultiDex.html

2. http://blog.osom.info/2014/10/multi-dex-to-rescue-from-infamous-65536.html

Also attached Android-support-mutidex.jar: http://download.csdn.net/detail/t12x3456/8143383


Additional precautions:

Com.android.dex.DexException:Multiple dex files define l{package}/buildconfig;
assume that you encounter this error, such as the following checks:

1. Whether the main project and the dependent Libraryproject package name are repeatedly
2. Check whether the master project and dependent Libraryproject contain repeated support.jar or other jar packages


How to resolve:

1. Change the Libraryproject package name

2. Remove the Repeat JAR package

3. Manually join the Lib package, add the following configuration

dependencies {            Compile filetree (dir: ' Libs ', include: [' *.jar '])            Compile project (': Lib-project-module ')        }





Android uses Android-support-multidex to solve the problem of Dex exceeding the number of methods, so that your app is no longer bursting

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.