如何在 Android 资源中使用 unicode?
Posted
技术标签:
【中文标题】如何在 Android 资源中使用 unicode?【英文标题】:How to use unicode in Android resource? 【发布时间】:2013-05-23 02:39:37 【问题描述】:我想在我的资源文件中使用this unicode 字符。
但无论我做什么,我都会以 dalvikvm 崩溃告终(用 android 2.3 和 4.2.2 测试):
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 -->
请注意,在代码中的 Java String 中使用它可以正常工作:
final String geolocation_icon = "\uD83D\uDCE1";
【问题讨论】:
您是否尝试在 XML 文件中使用 UTF-8?使用hexdump,能确认编码为0xF0 0x9F 0x93 0xA1
序列吗?
是的,是的,如果您查看上面的错误输出,您会发现它在抱怨它:input is not valid Modified UTF-8: illegal start byte 0xf0
【参考方案1】:
这样做
不要在 strings.xml 中保留有问题的表情符号
以编程方式添加它
<string name="hi_welcome_msg">Hi %1$s</string>
getString(R.string.hi_welcome_msg, user.getFullName() + " \uD83D\uDC4B" );
【讨论】:
【参考方案2】:您的角色 (U+1F4E1
) 不属于 Unicode BMP(基本多语言平面 - 范围从 U+0000
到 U+FFFF
)。
不幸的是,Android 对非 BMP 字符的支持非常弱(如果有的话)。 UTF-8
表示非 BMP 字符需要 4 个字节 (0xF0 0x9F 0x93 0xA1
)。但是,Android UTF-8
解析器最多只能理解 3 个字节(参见 here 和 here)。
当您使用 UTF-16
这个字符的代理形式表示时,它适用于您:"\uD83D\uDCE1"
。如果您能够在修改后的UTF-8
(又名CESU-8
)中编码每个代理UTF-16
字符-总共需要6个字节(代理对的每个成员UTF-8
中的3个字节),那么就有可能.但是,Android 也不明确支持CESU-8
。
因此,您当前的解决方案 - 在源代码中将此符号硬编码为代理 UTF-16
对似乎最简单,至少在 Android 开始完全支持非 BMP UTF-8
之前。
更新:这似乎在 Android 6.0 中得到了部分修复。 This commit 已合并到 Android 6 中,并允许在 XML 资源中存在 4 字节 UTF-8 字符。它不是完美的解决方案 - 它只会自动将 4 字节 UTF-8 转换为适当的代理对。但是,它允许将它们从源代码移动到 XML 资源中。遗憾的是,在您的应用程序停止支持除 6.0 及更高版本之外的任何 Android 版本之前,您无法使用此解决方案。
【讨论】:
这非常令人沮丧,因为它使 Class 文件比它需要的大得多。最好将这些 unicode 字符串分隔到arrays.xml
或 strings.xml
文件中。
@toobsco42:你可能想file a bug in Android bug database。
嗨,我有一个 xml 文件,其中包含“\uD83D\uDCE1”之类的代理对,但在尝试解析文件时出现错误,您能帮帮我吗?
@SWAppDev:您可以在 Java 源代码中使用代理对,但不能在资源 XML 中使用。
此website 可让您计算代理对。以上是关于如何在 Android 资源中使用 unicode?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android 的 TextView 中显示 Unicode 字符?