THE DEX 64K LIMIT IS NOT A PROBLEM ANYMORE, ALMOST
来源:互联网 发布:cors网络系统安全 编辑:程序博客网 时间:2024/05/05 23:28
- HOME
- RESOURCES
- POSTS
THE DEX 64K LIMIT IS NOT A PROBLEM ANYMORE, ALMOST
If you are an Android developer reading this, chances are you’ve at least heard of the dreaded 64k method limit in Dalvik. In a nutshell, the issue is that in a DEX file, you can reference a very large number of methods, but you can only invoke the first 65,536 of them, because that’s all the room you have in the method invocation set. If your source code and all those cool libraries that you are using exceed this limit – kaboom!
UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
at com.android.dx.merge.DexMerger$6.updateIndex(DexMerger.java:502)
at com.android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.java:277)
at com.android.dx.merge.DexMerger.mergeMethodIds(DexMerger.java:491)
at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:168)
at com.android.dx.merge.DexMerger.merge(DexMerger.java:189)
at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:454)
at com.android.dx.command.dexer.Main.runMonoDex(Main.java:302)
at com.android.dx.command.dexer.Main.run(Main.java:245)
at com.android.dx.command.dexer.Main.main(Main.java:214)
at com.android.dx.command.Main.main(Main.java:106)
For more detailed information about the issue, read this detailed post on the topic.
Not to be deterred, the amazing Android developer community has come up with a few solutions, like this one from dmarcato, and this one from casidiablo. They work, but required you to do some serious acrobatics.
Eventually, Google decided to release an official solution for this in the form of the MultiDex Support Library which was first announced back in Oct ‘14 and Gradle support was added in v0.14.0 of the Android Gradle plugin a few weeks later.
Using the MultiDex Support Library
If you are using Android Studio, the process is very straight-forward. If you are not, I highly recommend migrating, as Google may soon drop support for the Eclipse ADT plugin and the old Ant based build system.
Step 1
Add the dependency for the MultiDex support library in your build.gradle
dependencies {
...
compile 'com.android.support:multidex:'
...
}
Step 2
Enable multi-dexing by setting the multiDexEnabled flag in the buildType or productFlavor section of your gradle configuration.
defaultConfig {
...
multiDexEnabled true
...
}
Now depending on your project, you have 3 options:
If you haven’t created your own Application class, simply declare android.support.multidex.MultiDexApplication as your application class in AndroidManifest.xml
<application <="" br=""> ....
android:name="android.support.multidex.MultiDexApplication"
...
If you already have your own Application class, make it extend android.support.multidex.MultiDexApplication instead of android.app.Application
If your Application class is extending some other class and you don’t want to or can’t change it, override attachBaseContext() as shown below:
public class MyApplication extends FooApplication {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
Whichever you choose, each option generates multiple dex files instead of a single massive one and also takes care of loading all the classes in each one of them at run-time. Neat, right?
Now, when you build the app, Gradle will generate multiple dex files and generate an APK that you can successfully run on a device/emulator.
You can see it in action in this sample app on Github.
Caveats
Out of memory issues
For projects with lots of dependencies, the build process may fail with the following error –
Error:Execution failed for task ':app:dexDebug'.
...
Error Code:
3
Output:
UNEXPECTED TOP-LEVEL ERROR:
java.lang.OutOfMemoryError: GC overhead limit exceeded
at com.android.dx.cf.cst.ConstantPoolParser.parse0(ConstantPoolParser.java:326)
...
To fix it, set the following dex options in the ‘android’ closure –
dexOptions {
incremental true
javaMaxHeapSize "4g"
}
Slow application startup
Based on our experience with this support library, it works fine in most cases. However, it has a big impact on application launch time with large apps on some devices like the Kindle Fire. Loading all the classes on application launch simply takes a long time, which results in a black screen being displayed for several seconds, or in some cases, ANR errors.
More details, best-practices and limitations about MultiDex can be found here.
Conclusion
While the library fixes the DEX 64K problem in most cases, it should be treated as a last resort. Before attempting to use it, you should audit your project for unwanted dependencies and remove as much unused code as possible using ProGuard. If you do go ahead and use it, make sure you test your app on older devices.
- 第十一周(职员有薪水了)
- (2)使用XFire方式发布WebService实例说明
- 使用远程桌面连接无法显示本地硬盘解决方法
- windows7 64位安装Oracle10g 32位出错解决方法
- 当我完善几年前的一个老项目时,我做了哪些改进 (转)
- THE DEX 64K LIMIT IS NOT A PROBLEM ANYMORE, ALMOST
- HBase Java API详解
- 《剑指Offer》学习笔记--面试题65:滑动窗口的最大值
- 一道华为面试题
- 数据分析工具汇总
- Markdown编辑器尝鲜
- Linux学习篇之---Ubuntu14.04防火墙配置
- LeeCode 82 Remove Duplicates from Sorted List II
- 将JSON转成表格形式