关于Android方法数量限制的问题
来源:互联网 发布:伴奏升调降调软件 编辑:程序博客网 时间:2024/06/05 00:56
限制Android方法数量的原因是:
Android应用以DEX文件的形式存储字节码文件,在Dalvik字节码规范里,方法引用索引method referenceindex只有16位,即65536个。
Op & Format
Mnemonic / Syntax
Arguments
6e..72 35c
invoke-kind {vC, vD, vE, vF, vG}, meth@BBBB
B: method reference index (16 bits)
注意是method reference,这里限制的是自己代码、Android框架、第三方库三者方法数量的总和。
dex里方法只能索引65536个,但是报错不在这里。Android打包dex的过程如下:
//Main.Java
-> main() -> run() ->不分包执行runMonoDex()(或者分包执行runMultiDex())-> writeDex()
// DexFile
->toDex() -> toDex0()
// MethodIdsSection extends MemberIdsSection extends UniformItemSection extends Section
->Section 的prepare() -> UniformItemSection的prepare0() ->MemberIdsSection的orderItems() -> getTooManyMembersMessage()
//Main.java
->getTooManyIdsErrorMessage()
MemberIdsSection里执行了这么一段代码
protected void orderItems() {
int idx = 0;
if (items().size() >DexFormat.MAX_MEMBER_IDX + 1) { throw newDexIndexOverflowException(getTooManyMembersMessage()); } for (Object i : items()) { ((MemberIdItem) i).setIndex(idx); idx++; }}
getTooManyMembersMessage核心代码如下:构建了错误信息字符串。
private String getTooManyMembersMessage() {
try {
String memberType = this instanceofMethodIdsSection ? “method” : “field”;
formatter.format(“Too many %s references:%d; max is %d.%n” +
Main.getTooManyIdsErrorMessage() + “%n” +
“References bypackage:”,
memberType, items().size(),DexFormat.MAX_MEMBER_IDX + 1);
return formatter.toString();
}
}
}
可见代码里检测了方法数量的上限,超过就会报错。这里的限制DexFormat.MAX_MEMBER_IDX
出自
public final classDexFormat {
/**
* Maximum addressable field or methodindex.
* The largest addressable member is0xffff, in the “instruction formats” spec as field@CCCC or
* meth@CCCC.
*/
public static final int MAX_MEMBER_IDX =0xFFFF;
}
因此方法不能超过65536。这里的根源还是在dex字节码规范里方法引用索引的限制,但是强制报错是在这里限制的。
另外,域的数量也有此限制。
错误信息:
Error:Errorconverting bytecode to dex:
Cause:com.android.dex.DexIndexOverflowException:field ID not in [0, 0xffff]: 65536(笔者开发时遇到的是域数量问题,方法数量问题错误信息于此类似)
:XXXXXX:transformClassesWithDexForDebug FAILED
Error:Executionfailed for task ‘:XXXXXX:transformClassesWithDexForDebug’.
com.android.build.api.transform.TransformException:com.android.ide.common.process.ProcessException:java.util.concurrent.ExecutionException:com.android.ide.common.process.ProcessException:org.gradle.process.internal.ExecException: Process ‘command ‘C:\ProgramFiles\Java\jdk1.8.0_73\bin\java.exe” finished withnon-zero exit value 2
解决方法:
Google官方出的分包方案,采用MultiDex支持库
1,配置building.gradle,开启MultiDex
android {
defaultConfig { multiDexEnabled true}
}
dependencies{
compile’com.android.support:multidex:1.0.0’
}
2,配置应用
方法1:在AndroidManifest.xml的application中声明android.support.multidex.MultiDexApplication;
- 关于Android方法数量限制的问题
- 关于Android方法数量限制的问题
- Android超出方法数量限制问题
- 关于 Golang 限制goroutine的数量
- 有物品数量限制的背包问题
- Linux进程关于文件描述符的数量限制
- Linux进程关于文件描述符的数量限制
- C++ 限制类对象的数量的方法
- socket端口数量限制问题
- socket端口数量限制问题
- socket端口数量限制问题
- socket端口数量限制问题
- socket端口数量限制问题
- FeatureLayer.MODE_SNAPSHOT限制数量问题
- ShiroFilterFactoryBean过滤器数量限制问题
- BearSkill实用方法之UITextField限制输入的字符数量
- 关于Android Studio的RatingBar显示出来的星星数量与numStars设置的数量不符的问题
- Android实现限制EditText输入文字的数量
- 3.表单标签
- JS中String对象与Array对象常用基础知识
- linux性能 --》load average解读
- LeetCode 70 Climbing Stairs
- unity3d安装后打开失败(crashes while startup after install)
- 关于Android方法数量限制的问题
- Lua Function学习
- 解决android studio 中SVN和git冲突 无法提交代码
- Java多线程的实现
- Source Insight 4.0 常用设置和快捷键大全(一)
- SVG 转 图片
- UML关系(泛化,实现,依赖,关联(聚合,组合))
- Dynamic Web Module 3.0 requires Java 1.6 or newer
- 图像的仿射变换