Building Apps with Over 65 K Methods (the total number of APP Reference Methods exceeds 65536), using APP
This article is translated from http://developer.android.com/intl/zh-cn/tools/building/multidex.html?about. This section describes the cause and solution of building failure when the number of functions in the Android App exceeds 65536!
------------------------- Split line --------------------------------------------------
As android platform continues to grow, the size of android apps also increases. When your application contains the referenced library to a certain scale, you will encounter a build error, which indicates that your program has reached the limit of the android application framework. The following error message is reported in the early build system:
Conversion to Dalvik format failed:Unable to execute dex: method ID not in [0, 0xffff]: 65536
The build system of the latest version will display different errors. This is the prompt message for the same problem:
trouble writing output:Too many field references: 131000; max is 65536.You may try using --multi-dex option.
The two errors show a common number: 65536. This number indicates the total number of callable methods for a single Dalvik executable (DEX) bytecode file. If you have already created an android Application and received this error, congratulations! You have too many code! This document describes how to break through this restriction and continue to build your app.
About the 65 K Reference Limit
The APK file contains the Executable bytecode file (Dalvik Executable DEX) used to run your application to compile code ). The Dalvik executable specification limits the total number of methods referenced in a single DEX file, including the Android framework method and library method, to 65,536. To overcome this limitation, You need to configure the Build Process of your application and generate multiple DEX files, called multidex configuration.
Multidex support prior to Android 5.0
The earlier versions of Android use the Dalvik runtime to execute application code. By default, Dalvik limits the application, each APK a classes. dex bytecode file. To address this restriction, you can use the multidex support library to become part of the primary DEX file of your application, and then try to obtain additional DEX files and the code they contain.
Multidex support for Android 5.0 and higher
Android and later versions use ART runtime, which supports native loading of multiple dex files from the APK file. During installation of the pre-compiled application by ART, it will scan the class (. N). dex file and compile it into a single. oat file through the Android device for execution. For more information about running Android5.0, see Introducing ART.
Avoiding the 65 K Limit
Before configuring the number of methods that your application can use, you should take measures to reduce the total number of calls to your application code, includes methods in your application code and library-defined methods. The following policies can help you avoid exceeding the DEX reference limit:
View the direct and indirect dependencies of your application: Make sure that the usage of the library contained in your app matches the amount of code. A common counterexample is that it contains a large amount of code, but has little use. Reducing the library dependency of your app can often help you avoid dex reference restrictions.
Delete unused code obfuscation (code with ProGuard)): The configuration can run your app's ProGuard and make sure that you can slim down your app while building it.
Using these technologies can help you avoid the need to enable more method references when changing program build configurations. These steps are important for markets with high bandwidth costs.
Using ing Your App for Multidex with Gradle
The Android plug-in Gradle supports multidex in Android SDK Build Tools 21.1 and later versions as part of the Build configuration. Before configuring multidex for your app, use SDK Manager to update Android SDKBuild Tools and Android Support Repository to the latest version.
Before using multidex configuration in your app, you need to make some modifications to your program development. Follow these steps:
1. Modify Your Gradle build configuration to enable multidex
2. Modify Your AndroidManifest to reference the MultiDexApplication class.
Modify the build. gradle configuration to reference the support library and enable multidex output, as shown in the following build. gradle snippet.
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'}
Note: You can set multiDexEnable in defaultConfig, buildType, or productFlavor of the build. gradle file.
Add MultiDexApplication class to your AndroidManifest application element:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.multidex.myapplication"> <application ... android:name="android.support.multidex.MultiDexApplication"> ... </application></manifest>
When these configurations are added to an application, the Android build tool builds a dex (classes. dex) and continues building as needed (classes2.dex, classes3.dex ). Then the build system packages them into the same apk.
Note: If your app uses your own defined Application class, you can override the attachBaseContext () method and call MultiDex. install (this) to implement multidex. For more information, see MultiDexApplication
Limitations of the multidex support library
You should be aware that the multidex support library has some known limitations, so when you merge it into your application, you need to test it:
1. The installation of the dex file on the Data Partition of the Startup Device is very complicated. If the second-level dex file is too large, the program may not respond (ANR ). In this case, you should apply code reduction techniques with ProGuard to reduce the size of the. dex file and delete unused part of the code.
2. the program cannot use multidex in versions earlier than Android4.0 (API level 14) due to a Dalvik linearAlloc bug (Issue 22586) (http:// B .android.com/22586) if you use a version earlier than API Level 14, make sure that your application is executed to test whether your program has problems at startup or when a specific class is loaded. Code reduction can eliminate these potential problems.
3. The application uses the multidex configuration to Issue very large memory allocation requests, which may cause a runtime crash due to a Dalvik linearAlloc bug (Issue 78035) (http:// B .android.com/78035 ).
4. complex requests may be required for the primary dex file during Dalvik runtime execution. Android build tooling updates process Android requirements, but other required ded libraries may have additional dependencies, including calling local java code. Some libraries may not be available until the multidex build tools update allows you to specify classes that must be included in the main dex file.
Optimizing Multidex Development Builds
The multidex configuration requires a significant increase in the build processing time, because the build system must make complex decisions to determine which classes must be included in the primary dex file and which classes can be included in the second-level dex file. This means that regular build execution and multidex are part of the development process and usually take longer, which may slow down your program development progress.
To reduce the build time of multidex output, you should create two variables to use the Android build output plug-in Gradle productFlavors: a development flavor and a production flavor.
A development flavor, set a minimum SDK version of 21. This setting generates multidex output much faster than using the ART-supported format. The release flavor, set a minimum SDK version to match the minimum supported version of your project. This setting generates a multidex APK, which is compatible with more devices, but takes a longer time to build it.
The following build configuration example demonstrates how to set these flavors in the Gradle build file:
Android {productFlavors {// Define separate dev and prod product flavors. dev {// dev utilizes minSDKVersion = 21 to allow the Android gradle plugin // to pre-dex each module and produce an APK that can be tested on // Android Lollipop without time consuming dex merging processes. minSdkVersion 21} prod {// The actual minSdkVersion for the application. minSdkVersion 14 }}... buildTypes {release {runProguard true proguardFiles getdefadefaproguardfile('proguard-android.txt '), 'proguard-rules. pro' }}} dependencies {compile 'com. android. support: multidex: 1.0.0 '}View Code
After the configuration is changed, you can use the dev productFlavor and debug buildType attributes that are combined with the devDebug variable of the app. Use this to create a minSdkVersion for Android API Level 21 and enable the multidex debug app without using proguard. These settings enable the Android gradle plug-in to perform the following operations:
1. Build each module of the application (including dependent libraries) as a separate dex file. This is usually called pre-dexing.
2. the APK file is not modified for each dex file.
3. Most importantly, the module files of dex will not be combined, so you can avoid determining the long-running computing of the content of the primary dex file.
These settings lead to rapid and incremental building, because only the module that modifies the dex file will be re-computed and repackaged into an APK file. These settings can only be used to test Android 5.0 and later devices. However, by implementing the configured flavors, You can execute the normal build release-appropriate minimum SDK and proguard settings
You can also create other variables, including building prodDebug variables, which takes longer to build, but can be used for development outside of the test. If you execute the gradle task from the command line, you can use the standard command to append DevDebug (for example,./gradlew installDevDebug) at the end ).
For more information about using flavors and Gradle tasks, see Gradle Plugin User Guide (http://tools.android.com/tech-docs/new-build-system/user-guide)
Tip:You can also provide a custom list or define an application class for each flavor, allowing you to use the MultiDexApplication application class library or call MultiDex. install () when the variable is needed ().
Using Build Variants in Android Studio
Build variants is very useful for managing the multidex Build process. Android Studio can use visual operations to select these variables.
1. Open the Build Variants window in left-sidebar (usually in the lower left of Android studio)
2. Click the name of Build Variants to select different variables, as shown in figure 1.
When using instrumentation tests in multidex applications, additional configuration is required. Because the code is not located in a single DEX file in the multidex application. Therefore, instrumentation tests cannot run normally unless the program is configured with multidex.
To use instrumentation tests to test the multidex app, you must configure MultiDexTestRunner.
The following build. gradle file demonstrates how to configure the test Runner:
android { defaultConfig { ... testInstrumentationRunner "com.android.test.runner.MultiDexTestRunner" }}
Note: With Android Plugin for Gradle versions lower than 1.1, you need to add the following dependency for multidex-instrumentation:
dependencies { androidTestCompile('com.android.support:multidex-instrumentation:1.0.1') { exclude group: 'com.android.support', module: 'multidex' } }
You can use the instrumentation tests runner class to directly or expand it to meet your testing needs. Alternatively, you can overwrite onCreate in the existing instrumentation:
public void onCreate(Bundle arguments) { MultiDex.install(getTargetContext()); super.onCreate(arguments); ...}
Note: Use of multidex for creating a test APK is not currently supported.