2

目前我对以下代码有疑问:

String a = "0932300090";
byte[] b = a.getBytes(Charset.forName("UCS-2"));
Log.d("MTINH",Arrays.toString(b));

此代码已在两种不同的设备上使用过,一种运行 Android 8.0,另一种运行 Android 8.1,我得到了两种不同的结果:

在安卓 8.0 中:

-1, -2, 48, 0, 57, 0, 51, 0, 50, 0, 51, 0, 48, 0, 48, 0, 48, 0, 57, 0, 48, 0

在安卓 8.1 中:

-2, -1, 0, 48, 0, 57, 0, 51, 0, 50, 0, 51, 0, 48, 0, 48, 0, 48, 0, 57, 0, 48

结果似乎是成对交换的:[-1 -2] vs [-2 -1] ... [48 0] vs [0 48]。

那么这里的问题是什么?Java或Android有什么变化吗?

4

1 回答 1

3

UCS-2 编码UTF-16Android 8.x 和 9.0上有效。在 Android 8.1 上,android 工程对 UTF-16 编码进行了以下更改。

请注意,BOM 标记 (-2, -1) 包含在输出中。如果您需要跨设备的一致结果,您可以选择使用 UTF-16BE。以下是行为更改的详细信息。

UTF-16 字符集输出字节顺序

UTF-16Charset(通过orjava.nio.charset.Charset.forName("UTF-16")获得java.nio.charset.StandardCharsets.UTF_16)现在将字符串编码为带有字节顺序标记的大端 UTF-16 字节,正如 javadoc 所说的那样。以前,它使用字节顺序标记编码为 little-endian,这与文档相矛盾。

这也改变了调用getBytes("UTF-16")字符串的结果。这对使用UTF-16Charset 对字符串进行编码和解码的代码没有影响,因为解码遵循字节顺序标记。它只影响使用UTF-16Charset 进行编码的代码,然后假定生成的字节是小端的,例如通过使用忽略字节顺序标记的机制对它们进行解码。

想要使用字节顺序标记编码为 little-endian 的用户可以使用x-UTF-16LE-BOMCharset。(请注意,此字符集不应用于解码字节,除非它们已知为小端。)

于 2018-07-17T09:59:52.547 回答