1page.title=Building Apps with Over 65K Methods 2page.tags="65536","references","max","65k","dex","64k","multidex","multi-dex","methods"</p> 3 4@jd:body 5 6<div id="qv-wrapper"> 7 <div id="qv"> 8 <h2>In this document</h2> 9 <ol> 10 <li><a href="#about"> 11 About the 65K Reference Limit</a> 12 <ol> 13 <li><a href="#mdex-pre-l">Multidex support prior to Android 5.0</a></li> 14 <li><a href="#mdex-on-l">Multidex support for Android 5.0 and higher</a></li> 15 </ol> 16 </li> 17 <li><a href="#avoid"> 18 Avoiding the 65K Limit</a></li> 19 <li><a href="#mdex-gradle"> 20 Configuring Your App for Multidex with Gradle</a> 21 <ol> 22 <li><a href="#limitations"> 23 Limitations of the multidex support library</a></li> 24 </ol> 25 </li> 26 <li><a href="#dev-build"> 27 Optimizing Multidex Development Builds</a> 28 <ol> 29 <li><a href="#variants-studio"> 30 Using Build Variants in Android Studio</a></li> 31 </ol> 32 </li> 33 <li><a href="#testing"> 34 Testing Multidex Apps</a></li> 35 </ol> 36 37 <h2>See Also</h2> 38 <ol> 39 <li><a href="{@docRoot}tools/help/proguard.html">ProGuard</a> 40 </li> 41 </ol> 42 </div> 43</div> 44 45 46<p> 47 As the Android platform has continued to grow, so has the size of Android apps. When your 48 application and the libraries it references reach a certain size, you encounter build errors that 49 indicate your app has reached a limit of the Android app build architecture. Earlier versions of 50 the build system report this error as follows: 51</p> 52 53<pre> 54Conversion to Dalvik format failed: 55Unable to execute dex: method ID not in [0, 0xffff]: 65536 56</pre> 57 58<p> 59 More recent versions of the Android build system display a different error, which is an 60 indication of the same problem: 61</p> 62 63<pre> 64trouble writing output: 65Too many field references: 131000; max is 65536. 66You may try using --multi-dex option. 67</pre> 68 69<p> 70 Both these error conditions display a common number: 65,536. This number is significant in that 71 it represents the total number of references that can be invoked by the code within a single 72 Dalvik Executable (dex) bytecode file. If you have built an Android app and received this error, 73 then congratulations, you have a lot of code! This document explains how to move past this 74 limitation and continue building your app. 75</p> 76 77<p class="note"> 78 <strong>Note:</strong> The guidance provided in this document supersedes the guidance given in 79 the Android Developers blog post <a href= 80 "http://android-developers.blogspot.com/2011/07/custom-class-loading-in-dalvik.html">Custom Class 81 Loading in Dalvik</a>. 82</p> 83 84 85<h2 id="about">About the 65K Reference Limit</h2> 86 87<p> 88 Android application (APK) files contain executable bytecode files in the form of <a href= 89 "https://source.android.com/devices/tech/dalvik/">Dalvik</a> Executable (DEX) files, which 90 contain the compiled code used to run your app. The Dalvik Executable specification limits the 91 total number of methods that can be referenced within a single DEX file to 65,536, including 92 Android framework methods, library methods, and methods in your own code. Getting past this limit 93 requires that you configure your app build process to generate more than one DEX file, known as a 94 <em>multidex</em> configuration. 95</p> 96 97 98<h3 id="mdex-pre-l">Multidex support prior to Android 5.0</h3> 99 100<p> 101 Versions of the platform prior to Android 5.0 use the Dalvik runtime for executing app code. By 102 default, Dalvik limits apps to a single classes.dex bytecode file per APK. In order to get around 103 this limitation, you can use the <a href="{@docRoot}tools/support-library/features.html#multidex"> 104 multidex support library</a>, which becomes part of the primary DEX file of your app and then 105 manages access to the additional DEX files and the code they contain. 106</p> 107 108 109<h3 id="mdex-on-l">Multidex support for Android 5.0 and higher</h3> 110 111<p> 112 Android 5.0 and higher uses a runtime called ART which natively supports loading multiple dex 113 files from application APK files. ART performs pre-compilation at application install time which 114 scans for classes(..N).dex files and compiles them into a single .oat file for execution by the 115 Android device. For more information on the Android 5.0 runtime, see <a href= 116 "https://source.android.com/devices/tech/dalvik/art.html">Introducing ART</a>. 117</p> 118 119 120<h2 id="avoid">Avoiding the 65K Limit</h2> 121 122<p> 123 Before configuring your app to enable use of 65K or more method references, you should take steps 124 to reduce the total number of references called by your app code, including methods defined by 125 your app code or included libraries. The following strategies can help you avoid hitting the dex 126 reference limit: 127</p> 128 129<ul> 130 <li> 131 <strong>Review your app's direct and transitive dependencies</strong> - Ensure any large library 132 dependency you include in your app is used in a manner that outweighs the amount of code 133 being added to the application. A common anti-pattern is to include a very large library 134 because a few utility methods were useful. Reducing your app code dependencies can often help 135 you avoid the dex reference limit. 136 </li> 137 <li> 138 <strong>Remove unused code with ProGuard</strong> - Configure the <a href= 139 "{@docRoot}tools/help/proguard.html">ProGuard</a> settings for your app to run ProGuard and 140 ensure you have shrinking enabled for release builds. Enabling shrinking ensures you 141 are not shipping unused code with your APKs. 142 </li> 143</ul> 144 145 146<p> 147 Using these techniques can help you avoid the build configuration changes required to enable more 148 method references in your app. These steps can also decrease the size of your APKs, which is 149 particularly important for markets where bandwidth costs are high. 150</p> 151 152 153<h2 id="mdex-gradle">Configuring Your App for Multidex with Gradle</h2> 154 155<p> 156 The Android plugin for Gradle available in Android SDK Build Tools 21.1 and higher supports 157 multidex as part of your build configuration. Make sure you update the Android SDK Build Tools 158 tools and the Android Support Repository to the latest version using the <a href= 159 "{@docRoot}tools/help/sdk-manager.html">SDK Manager</a> before attempting to configure your app 160 for multidex. 161</p> 162 163<p> 164 Setting up your app development project to use a multidex configuration requires that you make a 165 few modifications to your app development project. In particular you need to perform the 166 following steps: 167</p> 168 169<ul> 170 <li>Change your Gradle build configuration to enable multidex</li> 171 <li>Modify your manifest to reference the {@link android.support.multidex.MultiDexApplication} 172 class</li> 173</ul> 174 175<p> 176 Modify your app Gradle build file configuration to include the support library and enable 177 multidex output, as shown in the following Gradle build file snippet: 178</p> 179 180<pre> 181android { 182 compileSdkVersion 21 183 buildToolsVersion "21.1.0" 184 185 defaultConfig { 186 ... 187 minSdkVersion 14 188 targetSdkVersion 21 189 ... 190 191 // Enabling multidex support. 192 multiDexEnabled true 193 } 194 ... 195} 196 197dependencies { 198 compile 'com.android.support:multidex:1.0.0' 199} 200</pre> 201 202<p class="note"> 203 <strong>Note:</strong> You can specify the <code>multiDexEnabled</code> setting in the 204 <code>defaultConfig,</code> <code>buildType</code>, or <code>productFlavor</code> sections of 205 your Gradle build file. 206</p> 207 208 209<p> 210 In your manifest add the {@link android.support.multidex.MultiDexApplication} class from the 211 multidex support library to the application element. 212</p> 213 214<pre> 215<?xml version="1.0" encoding="utf-8"?> 216<manifest xmlns:android="http://schemas.android.com/apk/res/android" 217 package="com.example.android.multidex.myapplication"> 218 <application 219 ... 220 android:name="android.support.multidex.MultiDexApplication"> 221 ... 222 </application> 223</manifest> 224</pre> 225 226<p> 227 When these configuration settings are added to an app, the Android build tools construct a 228 primary dex (classes.dex) and supporting (classes2.dex, classes3.dex) as needed. The build system 229 will then package them into an APK file for distribution. 230</p> 231 232<p class="note"> 233 <strong>Note:</strong> If your app uses extends the {@link android.app.Application} class, you 234 can override the attachBaseContext() method and call MultiDex.install(this) to enable multidex. 235 For more information, see the {@link android.support.multidex.MultiDexApplication} reference 236 documentation. 237</p> 238 239<h3 id="limitations">Limitations of the multidex support library</h3> 240 241<p> 242 The multidex support library has some known limitations that you should be aware of and test for 243 when you incorporate it into your app build configuration: 244</p> 245 246<ul> 247 <li>The installation of .dex files during startup onto a device's data partition is complex and 248 can result in Application Not Responding (ANR) errors if the secondary dex files are large. In 249 this case, you should apply code shrinking techniques with ProGuard to minimize the size of dex 250 files and remove unused portions of code. 251 </li> 252 253 <li>Applications that use multidex may not start on devices that run versions of the platform 254 earlier than Android 4.0 (API level 14) due to a Dalvik linearAlloc bug (Issue <a href= 255 "http://b.android.com/22586">22586</a>). If you are targeting API levels earlier than 14, make 256 sure to perform testing with these versions of the platform as your application can have issues 257 at startup or when particular groups of classes are loaded. Code shrinking can reduce or possibly 258 eliminate these potential issues. 259 </li> 260 261 <li>Applications using a multidex configuration that make very large memory allocation 262 requests may crash during run time due to a Dalvik linearAlloc limit (Issue <a href= 263 "http://b.android.com/78035">78035</a>). The allocation limit was increased in Android 4.0 (API 264 level 14), but apps may still run into this limit on Android versions prior to 265 Android 5.0 (API level 21). 266 </li> 267 268 <li>There are complex requirements regarding what classes are needed in the primary dex file when 269 executing in the Dalvik runtime. The Android build tooling updates handle the Android 270 requirements, but it is possible that other included libraries have additional dependency 271 requirements including the use of introspection or invocation of Java methods from native code. 272 Some libraries may not be able to be used until the multidex build tools are updated to allow you 273 to specify classes that must be included in the primary dex file. 274 </li> 275</ul> 276 277 278<h2 id="dev-build">Optimizing Multidex Development Builds</h2> 279 280<p> 281 A multidex configuration requires significantly increased build processing time because the build 282 system must make complex decisions about what classes must be included in the primary DEX file 283 and what classes can be included in secondary DEX files. This means that routine builds performed 284 as part of the development process with multidex typically take longer and can potentially slow 285 your development process. 286</p> 287 288<p> 289 In order to mitigate the typically longer build times for multidex output, you should create two 290 variations on your build output using the Android plugin for Gradle 291 <a href="http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Product-flavors"> 292 {@code productFlavors}</a>: a development flavor and a production flavor. 293</p> 294 295<p> 296 For the development flavor, set a minimum SDK version of 21. This setting generates multidex 297 output much faster using the ART-supported format. For the release flavor, set a minimum SDK 298 version which matches your actual minimum support level. This setting generates a multidex APK 299 that is compatible with more devices, but takes longer to build. 300</p> 301 302<p> 303 The following build configuration sample demonstrates the how to set up these flavors in a Gradle 304 build file: 305</p> 306 307<pre> 308android { 309 productFlavors { 310 // Define separate dev and prod product flavors. 311 dev { 312 // dev utilizes minSDKVersion = 21 to allow the Android gradle plugin 313 // to pre-dex each module and produce an APK that can be tested on 314 // Android Lollipop without time consuming dex merging processes. 315 minSdkVersion 21 316 } 317 prod { 318 // The actual minSdkVersion for the application. 319 minSdkVersion 14 320 } 321 } 322 ... 323 buildTypes { 324 release { 325 runProguard true 326 proguardFiles getDefaultProguardFile('proguard-android.txt'), 327 'proguard-rules.pro' 328 } 329 } 330} 331dependencies { 332 compile 'com.android.support:multidex:1.0.0' 333} 334</pre> 335 336<p> 337 After you have completed this configuration change, you can use the <code>devDebug</code> variant 338 of your app, which combines the attributes of the <code>dev</code> productFlavor and the 339 <code>debug</code> buildType. Using this target creates a debug app with proguard disabled, 340 multidex enabled, and minSdkVersion set to Android API level 21. These settings cause the Android 341 gradle plugin to do the following: 342</p> 343 344<ol> 345 <li>Build each module of the application (including dependencies) as separate dex files. This is 346 commonly referred to as pre-dexing. 347 </li> 348 349 <li>Include each dex file in the APK without modification. 350 </li> 351 352 <li>Most importantly, the module dex files will not be combined, and so the long-running 353 calculation to determine the contents of the primary dex file is avoided. 354 </li> 355</ol> 356 357<p> 358 These settings result in fast, incremental builds, because only the dex files of modified modules 359 are recomputed and repackaged into the APK file. The APK that results from these builds can be 360 used to test on Android 5.0 devices only. However, by implementing the configuration as a flavor, 361 you preserve the ability to perform normal builds with the release-appropriate minimum SDK level 362 and proguard settings. 363</p> 364 365<p> 366 You can also build the other variants, including a <code>prodDebug</code> variant 367 build, which takes longer to build, but can be used for testing outside of development. 368 Within the configuration shown, the <code>prodRelease</code> variant would be the final testing 369 and release version. If you are executing gradle tasks from the command line, you can use 370 standard commands with <code>DevDebug</code> appended to the end (such as <code>./gradlew 371 installDevDebug</code>). For more information about using flavors with Gradle tasks, see the 372 <a href="http://tools.android.com/tech-docs/new-build-system/user-guide">Gradle Plugin User 373 Guide</a>. 374</p> 375 376<p> 377 <strong>Tip:</strong> You can also provide a custom manifest, or a custom application class for each 378 flavor, allowing you to use the support library MultiDexApplication class, or calling 379 MultiDex.install() only for the variants that need it. 380</p> 381 382 383<h3 id="variants-studio">Using Build Variants in Android Studio</h3> 384 385<p> 386 Build variants can be very useful for managing the build process when using multidex. Android 387 Studio allows you to select these build variants in the user interface. 388</p> 389 390<p> 391 To have Android Studio build the "devDebug" variant of your app: 392</p> 393 394<ol> 395 <li>Open the <em>Build Variants</em> window from the left-sidebar. The option is located next to 396 <em>Favorites</em>. 397 </li> 398 399 <li>Click the name of the build variant to select a different variant, as shown in Figure 1. 400 </li> 401</ol> 402 403<img src="{@docRoot}images/tools/studio-build-variant.png" alt="" height="XXX" id="figure1"> 404<p class="img-caption"> 405 <strong>Figure 1.</strong> Screen shot of the Android Studio left panel showing a build variant. 406</p> 407 408<p class="note"> 409 <strong>Note</strong>: The option to open this window is only available after you have 410 successfully synchronized Android Studio with your Gradle build file using the <strong>Tools > 411 Android > Sync Project with Gradle Files</strong> command. 412</p> 413 414 415<h2 id="testing">Testing Multidex Apps</h2> 416 417<p> 418 When using instrumentation tests with multidex apps, additional configuration is required to 419 enable the test instrumentation. Because the location of code for classes in multidex apps is not 420 within a single DEX file, instrumentation tests do not run properly unless configured for 421 multidex. 422</p> 423 424<p> 425 To test a multidex app with instrumentation tests, configure the 426 <a href="{@docRoot}reference/com/android/test/runner/MultiDexTestRunner.html"> 427 MultiDexTestRunner</a> from the multidex testing support library. The following sample 428 {@code build.gradle} file demonstrates how to configure your build to use this test runner: 429</p> 430 431<pre> 432android { 433 defaultConfig { 434 ... 435 testInstrumentationRunner "com.android.test.runner.MultiDexTestRunner" 436 } 437} 438</pre> 439 440<p class="note"> 441 <strong>Note:</strong> With Android Plugin for Gradle versions lower than 1.1, you need to add 442 the following dependency for <code>multidex-instrumentation</code>: 443<pre> 444dependencies { 445 androidTestCompile('com.android.support:multidex-instrumentation:1.0.1') { 446 exclude group: 'com.android.support', module: 'multidex' 447 } 448} 449</pre> 450</p> 451 452 453<p> 454 You may use the instrumentation test runner class directly or extend it to fit your testing 455 needs. Alternatively, you can override onCreate in existing instrumentations like this: 456</p> 457 458<pre> 459public void onCreate(Bundle arguments) { 460 MultiDex.install(getTargetContext()); 461 super.onCreate(arguments); 462 ... 463} 464</pre> 465 466<p class="note"> 467 <strong>Note:</strong> Use of multidex for creating a test APK is not currently supported. 468</p> 469