概述:
在Android中单个dex文件能包含的最大方法数为 65536 。 这个方法数目来自,Android FrameWork,一依赖包,已经代码中包含的方法,还有些项目使用的第三方库里面的方法 的总和。
乍一看这个数字很大,一般不会超过。但是随着App的更新速度火箭般提高,和用户的各种需求大量增加,最终在产品的指挥下,项目越来越大。现如今,只要是比较大型的项目,都会遇到 65536 问题。
问题描述:
1.当dex方法数超过65536,我们会遇到这种情况:
无法正常编译,异常提示如下:
<code class="hljs tex has-numbering">Error:Execution failed for task ':duchazhushou:dexRelease'. > com.android.ide.common.internal.LoggedErrorException: Failed to run command: C:<span class="hljs-command">\Users</span><span class="hljs-command">\jeff</span><span class="hljs-command">\AppData</span><span class="hljs-command">\Local</span><span class="hljs-command">\Android</span><span class="hljs-command">\sdk</span><span class="hljs-command">\android</span>-sdk<span class="hljs-command">\build</span>-tools\21.1.1<span class="hljs-command">\dx</span>.bat --dex --output D:<span class="hljs-command">\dev</span><span class="hljs-command">\android</span><span class="hljs-command">\Duchazhushou</span>_TDT<span class="hljs-command">\duchazhushou</span><span class="hljs-command">\build</span><span class="hljs-command">\intermediates</span><span class="hljs-command">\dex</span><span class="hljs-command">\release</span> --input-list=D:<span class="hljs-command">\dev</span><span class="hljs-command">\android</span><span class="hljs-command">\Duchazhushou</span>_TDT<span class="hljs-command">\duchazhushou</span><span class="hljs-command">\build</span><span class="hljs-command">\intermediates</span><span class="hljs-command">\tmp</span><span class="hljs-command">\dex</span><span class="hljs-command">\release</span><span class="hljs-command">\inputList</span>.txt Error Code: 2 Output: UNEXPECTED TOP-LEVEL EXCEPTION: com.android.dex.DexIndexOverflowException: method ID not in <span class="hljs-special">[</span>0, 0xffff<span class="hljs-special">]</span>: 65536 at com.android.dx.merge.DexMerger<span class="hljs-formula">$6.updateIndex(DexMerger.java:502) at com.android.dx.merge.DexMerger$</span>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)</code>
2.还有一种情况,并非是方法数超出65536,会出现在低版本手机安装Apk时,异常停止。(这种情况,我们放在以后再说,今天主要解决AS multidex问题)
如今的博客论坛上,解决65536问题,大多是把dex拆分多个,即:分包。其实对于现在的项目来说,这种高强度的代码改动,非常繁琐麻烦。我不推荐。
Eclipse处理65536相当麻烦,必须在项目中加入gradle,然后用google的muldex进行分包。
所以我们今天只讨论AS解决65536的方法:
<code class="hljs coffeescript has-numbering"><span class="hljs-number">1.</span> 首先要使用包含 Android SDK Build Tools <span class="hljs-number">21.1</span> 或者以上版本的编译环境。 <span class="hljs-number">2.</span> 在 app -<span class="hljs-function">-></span> build.gradle -<span class="hljs-function">-></span> defaultConfig -<span class="hljs-function">-></span> 添加multiDexEnabled <span class="hljs-literal">true</span> <span class="hljs-number">3.</span> dependencies -<span class="hljs-function">-></span> 添加multidex依赖 ( complie <span class="hljs-string">'com.android.support:multidex:1.0.0'</span>)</code>
配置方面完成后,我们需要在代码上添加multidex支持:
三种方法:
-
Application 继承MultiDexApplication
-
在manifest中指定Application为MultiDexApplication
<code class="hljs ruby has-numbering"><<span class="hljs-constant">Application</span> <span class="hljs-symbol">android:</span>name=<span class="hljs-string">"android.support.multidex.MultiDexApplication"</span> <span class="hljs-symbol">android:</span>allowBackup=<span class="hljs-string">"ture"</span> <span class="hljs-symbol">android:</span>theme=“<span class="hljs-variable">@Style</span>/<span class="hljs-constant">AppTheme</span><span class="hljs-string">" android:label="</span><span class="hljs-variable">@Style</span>/app_name<span class="hljs-string">" android:icon="</span><span class="hljs-variable">@mipmap</span>/ic_launcher<span class="hljs-string">" > </Application></span></code>
3.在 继承Application的主方法类 重写 attachBaseContext方法 【注意:此方法要比 onCreter 提前】
<code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainApplication</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Application</span>{</span> <span class="hljs-annotation">@Override</span> protexted <span class="hljs-keyword">void</span> attachBaseContext(Context base){ <span class="hljs-keyword">super</span>.attachBaseContext(base); MultiDex.install(<span class="hljs-keyword">this</span>); } }</code>
完成以上操作,就可以避免65536问题呐!