Android 安卓:我的应用程序太大了,并且给出了;无法执行dex:method ID不在[0,0xffff]:65536“中?”;?
我正在尝试将我的应用程序与Box、Dropbox和Google Drive集成。所有这三项服务都需要许多第三方JAR。此外,我的应用程序已经需要一些第三方JAR。现在,当我尝试从eclipse运行应用程序时,出现以下错误: 无法执行dex:method ID不在[0,0xffff]:65536转换中 转换Dalvik格式失败:无法执行[0]中的dex:method ID, 0xffff]:65536 似乎发生此错误是因为我的应用程序有太多的方法。我相当确定这些方法大部分来自第三方JAR,因此试图通过简化代码来解决这一问题是不现实的。我在网上找到了这两条建议Android 安卓:我的应用程序太大了,并且给出了;无法执行dex:method ID不在[0,0xffff]:65536“中?”;?,android,dalvik,dx,Android,Dalvik,Dx,我正在尝试将我的应用程序与Box、Dropbox和Google Drive集成。所有这三项服务都需要许多第三方JAR。此外,我的应用程序已经需要一些第三方JAR。现在,当我尝试从eclipse运行应用程序时,出现以下错误: 无法执行dex:method ID不在[0,0xffff]:65536转换中 转换Dalvik格式失败:无法执行[0]中的dex:method ID, 0xffff]:65536 似乎发生此错误是因为我的应用程序有太多的方法。我相当确定这些方法大部分来自第三方JAR,因此试图
所以,我希望在这个问题上能得到一些建议。选项2是我的案例的解决方案吗?是否存在另一个我应该考虑的解决方案? < P> Delvik VM每一个DEX文件最多可以有65536种方法,这是因为字节码指令集没有方法引用多于16位的方法数(如注释中的“@丹弗斯指出的”)。
虽然可以使用多个dex文件修复此问题,但Facebook表示,他们可以在应用程序中部署这些文件来解决此问题。您也可以开发一个或多个dex文件作为主应用程序的插件,以单独的APK形式下载。APK将公开主应用程序将使用的某些组件——因为我不知道您与这些服务集成的性质,所以我无法对此提出更具体的建议。您可以使用自己的
签名
级别的自定义
来保护两个应用程序之间的通信。另外,作为奖励,如果使用第三方库增加了额外权限的要求,那么您只需要插件APK中的这些权限,从而使您的主APK更小。请参阅vm/linearloc.c,您可以找到以下代码:(安卓2.3.3下为5MiB,安卓4.0后为8MiB,作为我的调查)
#定义默认的最大长度(5*1024*1024)
LinearAllocHdr*pHdr
pHdr->mapleLength=默认最大长度
我想“Facebook补丁”是通过使用本机C指针来编辑这个内存的。
IMHO LinearAlloc问题和这个方法ID问题是不同的事情。我最近遇到了这个问题。在浏览web以获得更详细的实现后,我意识到除了以下内容之外,没有其他内容:
- 很好,但现在Gradle已经在了,有点过时了:
- 没有太多细节,但对如何做到这一点有一个模糊的想法:
dex
。因此,如果我可以针对库编译代码,但不将它们包含在classes.dex
中,然后将dex
库分开,然后在运行时将它们放在一起,那么应该可以工作。唯一需要解决的问题是类加载器,Facebook顺便提到了它
因此,通过一些反思和一些Groovy代码,我认为我找到了一种相对稳定的方法,将库和应用程序代码打包到单独的dex
文件中
是我编写的一个脚本,用于计算特定文件夹中每个jar中的方法数(以及总数)
一旦你计算了这些方法,你就可以专注于重构和删除繁重的库。***新****所有其他答案现在都过时了。这是新的解决方案
安卓5.0及更高版本
从文档中:
Android 5.0及更高版本使用一个名为ART的运行时,该运行时在本地
支持从应用程序APK文件加载多个dex文件。艺术
在应用程序安装时执行预编译,扫描
类(…N).dex文件,并将其编译为单个.oat文件,以便
由Android设备执行。更多关于Android的信息
5.0运行时,请参见介绍艺术
低于安卓5.0
达到65k方法限制的大多数问题都与在你的应用程序中使用乳齿状的Google Play服务有关。最近,您可以在使用它时获得更大的粒度 接下来,您只能使用所需的零件。这可能会解决问题,避免一些黑魔法,或者使用多重索引。例如,如果你只想在你的应用程序中使用谷歌地图(而你没有使用广告、钱包、谷歌服装、分析等等),那么使用整个依赖关系就是浪费时间/空间。您可以这样使用它:
compile com.google.android.gms:play-services-base:6.5.87
compile com.google.android.gms:play-services-maps:6.5.87
您可以在中阅读整个“部件”列表,您需要为此启用Dex支持。因此,您需要执行以下步骤:
compile com.google.android.gms:play-services-base:6.5.87
compile com.google.android.gms:play-services-maps:6.5.87
android {
defaultConfig {
...
multiDexEnabled = true
}
}
dependencies {
...
compile 'com.android.support:multidex:1.0.0'
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.multidex.App"> <application
android:name="android.support.multidex.MultiDexApplication">
</application>
</manifest>
public class App extends MultiDexApplication { .. }
public class App {
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
..
}
}