限制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;

<?xmlversion="1.0" encoding="utf-8"?>

<manifestxmlns:android="http://schemas.android.com/apk/res/android"

package="com.example.android.multidex.myapplication">

<application

...

android:name="android.support.multidex.MultiDexApplication">

...

</application>

</manifest>

方法2:让你自己的Application类继承MultiDexApplication

方法3:让你自己的Application类重写attachBaseContext 方法,

@Override

protected voidattachBaseContext(Context base) {

super.attachBaseContext(base);

MultiDex.install(this);

}

其他错误情况:

Error:java.lang.OutOfMemoryError: Java heap space.

Please assign morememory to Gradle in the project's gradle.properties file.

For example, thefollowing line, in the gradle.properties file, sets the maximum Java heap sizeto 1,024 MB:

<em>org.gradle.jvmargs=-Xmx1024m</em>

:XXXXXX:transformClassesWithDexForDebugFAILED

Error:Executionfailed for task ':XXXXXX:transformClassesWithDexForDebug'.

>com.android.build.api.transform.TransformException: java.lang.RuntimeException:com.android.ide.common.process.ProcessException:java.util.concurrent.ExecutionException:com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException:Process 'command 'C:\Program Files\Java\jdk1.8.0_73\bin\java.exe''finished with non-zero exit value 3

解决方法:

Building.gradle里

dexOptions {

javaMaxHeapSize "4g"

}

javaMaxHeapSize对应正则表达式是"\\d+[kKmMgGtT]?"4g指4G字节。

DexOptions类包含了获取JavaMaxHeapSize的方法,对应Building.gradle里dexOptions设置的javaMaxHeapSize。

参考:

http://source.android.com/devices/tech/dalvik/dalvik-bytecode.html

http://jayfeng.com/2016/03/10/%E7%94%B1Android-65K%E6%96%B9%E6%B3%95%E6%95%B0%E9%99%90%E5%88%B6%E5%BC%95%E5%8F%91%E7%9A%84%E6%80%9D%E8%80%83/

http://developer.android.com/intl/es/tools/building/multidex.html

关于Android方法数量限制的问题相关推荐

  1. 《Splunk智能运维实战》——3.6 制作每一主机不同请求方法数量的图表

    本节书摘来自华章计算机<Splunk智能运维实战>一书中的第3章,第3.6节,作者 [美]乔史·戴昆(Josh Diakun),保罗R.约翰逊(Paul R. Johnson),德莱克·默 ...

  2. Android中WebView加载本地Html,与JavaScript与Android方法相互传值...

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010046908/article/details/51759125 最近在做项目中,要使用High ...

  3. Android中WebView加载本地Html,与JavaScript与Android方法相互传值(续)...

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010046908/article/details/51809558 接着上篇Android中Web ...

  4. 识别IOS和android方法

    识别IOS和android方法 直接上代码,不管是app开发还是手机端web开发都有遇到苹果跟安卓手机兼容性的问题,有时不得不写两套方法,这里根据识别是苹果还是安卓手机后进行设置对应的样式,当然除了用 ...

  5. js调android方法失败,安卓开发学习之解决JS不能调用Android方法

    背景 这两天在做划词搜索时,需要让前端的js调用后端的Android方法,但总是调不成,经过搜索,问题解决,现记录成文. 解决方案 1.确定调用了webView.addJavascriptInterf ...

  6. Ubuntu共享WiFi(AP)给Android方法汇总

    Ubuntu共享WiFi(AP)给Android方法(手工配置) Android不支持Ad-hoc模式的WiFi.Windows 7软AP一个还是比较简单的. 本文介绍在Ubuntu下实现软AP.(需 ...

  7. ffmpeg移植Android方法以及常见问题汇总

    ffmpeg移植Android方法以及常见问题汇总: 1.在ffmpeg官网下载源码包,比如ffmpeg-2.3.在ffmpeg目录下增加Android.mk 和av.mk config.sh三个文件 ...

  8. CTF-Bugku逆向题Android方法归纳

    1.signin题目: reverse() 功能:反转数组里的元素的顺序 语法:arrayobject.reverse.() 这类方法会改变原来的数组,不可逆转 tostring() 功能:将各类进制 ...

  9. android 计算方法数量,如何精确计算Android应用的使用时长

    应用时长的计算友盟早期做法计算每个Activity的时长,然后全部相加就是App的使用时长.后来的做法是在客户端计算,如果应用离开小于30秒内又切回就将切走的时间也算入App的使用时长内. 本人觉得既 ...

最新文章

  1. linux怎么停止ssh服务,Linux 故障排除:关闭 SSH 会话后如何保存工作状态?
  2. python爬虫基础教程115_Python解析网页源代码中的115网盘链接实例
  3. index.html乱码问题,用apache打开文件index显示乱码为什么
  4. 在 RHEL 和 CentOS 上检查或列出已安装的安全更新的两种方法
  5. http://kylin.apache.org/development/new_metadata.html
  6. mysql二进制增量备份
  7. Java(随笔)——利用HTML,CSS,JavaScript,JQuery编写的简易计算器
  8. 外部方法调用内部_实战经验:通过类成员函数指针实现类方法调用
  9. Unity官方支持中文版啦!!!附教程——无需破解!
  10. 无线ap ntp服务器,我有一优科 ZoneFlex 7982 的无线AP,怎样可以进AP系统进行设置...
  11. 华为交换机5720常用命令
  12. 阿里云云计算助理工程师认证(ACA)
  13. Effie 致创作路上的独行者:动静相宜
  14. 电脑锁屏卡死以及任务栏卡死的解决办法
  15. 如何解决merge conflict的方法
  16. 微型计算机电路软件,微机控制电路
  17. 手写一个获取验证码的接口,超级简单
  18. F28335的储存器及其地址分配
  19. APMServ 5.2.6虚拟主机配置bug
  20. 2021总结web渗透测试岗位面试题(个人亲身经历的总结)

热门文章

  1. (原创)Python文件与文件系统系列(5)——stat模块
  2. 了解黑客的关键工具---揭开Shellcode的神秘面纱
  3. Prolog学习:数独和八皇后问题
  4. 基础篇9-python基本数据结构-列表
  5. 【124】排球基本技术
  6. Oracle 10g配置RMAN RECOVERY CATALOG
  7. iOS下JS与OC互相调用(七)--Cordova 基础
  8. iOS下JS与OC互相调用(三)--MessageHandler
  9. 所有接口添加plist文件的写法 swift
  10. Redis的集群模式