Android 项目开发填坑记 - NoSuchMethodError:(java.lang.System.arraycopy)
关键字:NoSuchMethodError
、System.arraycopy
、Native Method
0x00:奇怪的异常
应用新版本上线后观察错误日志,发现一个奇怪的 Crash 异常信息:
1 | lang.java.NoSuchMethodError: (java.lang.System.arraycopy) |
异常集中发生在 Android 4.4.2 和 Android 5.1 上面,System.arraycopy()
是一个系统函数,要说没这个方法倒是不会,但异常发生了,说明应用在找这个方法时发生了错误。
0x01:探究原因
根据异常日志,追踪到 System.arraycopy()
是 Base64.java 的 public static byte[] decode(byte[] source, int off, int len, int options)
方法里调用的。
经过查找 Android API 19~21 的系统源码,发现发生此问题的原因是 Android>=21 时,java.lang.System.arraycopy()
多了几个重载。
在 Android <=20 上:
1 | //java.lang.System 只有一个 arraycopy 方法 |
在 Android >=21 上:
1 | //java.lang.System |
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 使用的重载方法,避免编译器用错
1 | System.arraycopy(outBuff, 0, out, 0, outBuffPosn); |
2.使用 Arrays.copyOf ()
来替代 System.arraycopy()
1 | System.arraycopy(outBuff, 0, out, 0, outBuffPosn); |
虽然 Arrays.copyOf()
的方法实现最后还是调用的 System.arraycopy()
,但是不会调用到错误的重载方法。
PS:你可以通过下面的方式和我联系