前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android 项目开发填坑记 - NoSuchMethodError:(java.lang.System.arraycopy)

Android 项目开发填坑记 - NoSuchMethodError:(java.lang.System.arraycopy)

作者头像
他叫自己MR.张
发布2019-07-01 11:15:43
7610
发布2019-07-01 11:15:43
举报
文章被收录于专栏:Android必知必会Android必知必会

版权声明:本文为他叫自己Mr.张的原创文章,转载请注明出处,否则禁止转载。 https://cloud.tencent.com/developer/article/1452986

若移动端访问不佳,请使用 -> Github Page 版

关键字:NoSuchMethodErrorSystem.arraycopyNative Method

0x00:奇怪的异常

应用新版本上线后观察错误日志,发现一个奇怪的 Crash 异常信息:

代码语言:javascript
复制
lang.java.NoSuchMethodError: (java.lang.System.arraycopy)

异常集中发生在 Android 4.4.2 和 Android 5.1 上面,System.arraycopy() 是一个系统函数,要说没这个方法倒是不会,但异常发生了,说明应用在找这个方法时发生了错误。

0x01:探究原因

根据异常日志,追踪到 System.arraycopy()Base64.javapublic static byte[] decode(byte[] source, int off, int len, int options) 方法里调用的。

经过查找 Android API 19~21 的系统源码,发现发生此问题的原因是 Android>=21 时,java.lang.System.arraycopy() 多了几个重载。

在 Android <=20 上:

代码语言:javascript
复制
//java.lang.System 只有一个 arraycopy 方法
public static native void arraycopy(Object src, int srcPos,Object dst, int dstPos, int length);

在 Android >=21 上:

代码语言:javascript
复制
//java.lang.System
public static native void arraycopy(Object src, int srcPos,Object dst, int dstPos, int length);
/**
 * The byte[] specialized version of arraycopy().
 *
 * @hide internal use only
 */
public static void arraycopy(byte[] src, int srcPos, byte[] dst, int dstPos, int length){}

Base64.java 应该使用的是 native void arraycopy(Object src... ,但是会在 compileSdkVersion>=21 时使用重载的 arraycopy(byte[] src … ,那么运行在 Android <=20 的手机上时就会报 java.lang.NoSuchMethodError 的异常了。

总结下来就是:如果你在 Android 上使用了此 Base64 工具类,并且编译时使用的 Android 版本>=21,那么在低版本上你可能会遇到 java.lang.NoSuchMethodError: java.lang.System.arraycopy 的异常。之所以说是可能,是因为出现此异常时在开发平常的应用时不会发生,一般是使用修改后的系统 Jar 包调用系统隐藏方法时才容易出现。

0x02:解决方案

如何解决呢?有两个方法:

1.指定使用 arraycopy 使用的重载方法,避免编译器用错

代码语言:javascript
复制
System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
//替换成
System.arraycopy((Object) outBuff, 0, (Object) out, 0, outBuffPosn);

2.使用 Arrays.copyOf () 来替代 System.arraycopy()

代码语言:javascript
复制
System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
//替换成
out = Arrays.copyOf(outBuff, outBuffPosn);

虽然 Arrays.copyOf() 的方法实现最后还是调用的 System.arraycopy() ,但是不会调用到错误的重载方法。

PS:你可以通过下面的方式和我联系

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年02月09日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x00:奇怪的异常
  • 0x01:探究原因
  • 0x02:解决方案
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档