java如何在Android 9上保持UTF8的向后兼容性?
安卓9中引入的行为变化之一是更严格的UTF-8 decoder。如果我们有一个字节数组不是正确的UTF-8字符串(例如随机字节或一些二进制数据),并尝试从中创建一个字符串:
return new String(bytes)
Android会选择UTF-8作为首选编码(这很好),但在Android 9上返回的结果与旧版本的Android略有不同
我知道把随机字节转换成UTF-8字符串一开始听起来不是个好主意,但我现在需要向后兼容
是否有一个选项可以在所有Android版本上获得完全相同的字符串结果
编辑:
复制的步骤:
byte[] bytes = new byte[]{25, 17, 113, 18, 62, 121, -6, -71, 45, -126, -113, 122, 58, 49, -30, -53, -66, -7, 0, -41};
char[] password = new String(bytes).toCharArray();
byte[] passKey = PBEParametersGenerator.PKCS12PasswordToBytes(password);
Log.d("TEST", "Bytes: ".concat(Arrays.toString(passKey)));
Android的输出<;9.0:
[0, 25, 0, 17, 0, 113, 0, 18, 0, 62, 0, 121, -1, -3, 0, 45, -1, -3, -1, -3, 0, 122, 0, 58, 0, 49, -1, -3, 2, -2, -1, -3, 0, 0, -1, -3, 0, 0]
Android 9.0的输出:
[0, 25, 0, 17, 0, 113, 0, 18, 0, 62, 0, 121, -1, -3, -1, -3, 0, 45, -1, -3, -1, -3, 0, 122, 0, 58, 0, 49, -1, -3, 2, -2, -1, -3, 0, 0, -1, -3, 0, 0]
# 1 楼答案
您可以使用这段代码,它是从以前的Android版本的UTF-8解码器移植而来的
我通过创建一个20字节的随机数组,并与之前Android版本上的原始
new String(bytes).toCharArray()
实现进行了单元测试,然后重复了一百万次。我在多个旧版本的Android上没有看到任何差异原始源代码来自这里:https://android.googlesource.com/platform/libcore/+/a7752f4d22097346dd7849b92b9f36d0a0a7a8f3/libdvm/src/main/java/java/lang/String.java#245 为了简化它,我删除了处理非UTF8字符集的部分,如果使用
new String()
,那么UTF-8是使用的默认字符集,所以应该可以这段代码将使您获得想要的向后兼容性。但正如其他人所建议的那样,我建议尽可能寻找一个更简单的解决方案,它不依赖于Android版本(或其他组件,它们不受您的控制)