如何在Android资源中使用unicode?
我想在我的资源文件中使用这个 Unicode字符。
但无论我做什么,我都以dalvikvm崩溃(Android 2.3和4.2.2testing)结束:
W/dalvikvm( 8797): JNI WARNING: input is not valid Modified UTF-8: illegal start byte 0xf0 W/dalvikvm( 8797): string: '📡' W/dalvikvm( 8797): in Landroid/content/res/StringBlock;.nativeGetString:(II)Ljava/lang/String; (NewStringUTF) E/dalvikvm( 8797): VM aborting F/libc ( 8797): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 8797 (cz.ipex...)
我在我的资源文件中试过这些版本:
<string name="geolocation_icon" translatable="false">📡</string> <!-- HTML --> <string name="geolocation_icon" translatable="false">\uD83D\uDCE1</string> <!-- escaped unicode --> <string name="geolocation_icon" translatable="false">📡</string> <!-- unicode character -->
请注意,在代码中使用Javastring工作正常:
final String geolocation_icon = "\uD83D\uDCE1";
您的字符( U+1F4E1
)在Unicode BMP(基本多语言平面 – 范围从U+0000
到U+FFFF
)之外。
不幸的是,Android对非BMP字符的支持非常薄弱(如果有的话)。 非BMP字符的UTF-8
表示需要4个字节( 0xF0 0x9F 0x93 0xA1
)。 但是,Android的UTF-8
分析器只能理解3个字节的最大值(见这里和这里 )。
当你使用这个字符的UTF-16
代理forms表示法时,它适用于你: "\uD83D\uDCE1"
。 如果你能够在修改的UTF-8
(又名CESU-8
)中编码每个替代UTF-16
字符 – 总共需要6个字节( UTF-8
3个字节用于代理对的每个成员),那么这将是可能的。 但是,Android也不明确支持CESU-8
。
所以,你现在的解决scheme – 在代码UTF-16
对源代码进行硬编码似乎是最简单的,至less在Android开始全面支持非BMP UTF-8
。
更新 :这似乎是在Android 6.0中部分修复。 此提交已合并到Android 6中,并允许在XML资源中存在4字节的UTF-8字符。 它不是完美的解决scheme – 它会自动将4字节的UTF-8转换为适当的代理对。 但是,它允许将它们从源代码移到XML资源中。 不幸的是,你不能使用这个解决scheme,直到你的应用程序停止支持除6.0和更高版本之外的任何Android版本。