You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中Spannable转义首引号致Html.fromHtml输出异常问题

问题分析:Html.fromHtml解析带转义引号的CDATA时出错

Hey there! Let's dig into this issue you're facing as an Android newbie—this is actually a quirk (or edge-case bug) in Android's older Html.fromHtml() parser, and I'll break down what's going on:

1. 问题的核心原因

Your strings.xml uses an escaped quote (\") inside the CDATA block for the first <a> tag's href attribute, but here's the key point: CDATA sections in XML are meant to treat content as raw text, so you don't need to escape quotes inside them.

The older Html.fromHtml() method (the one you're using, without a mode parameter, which maps to pre-Android N behavior) can't handle this invalid escaped quote correctly. It misinterprets the \" as part of the attribute value, which breaks the entire <a> tag structure. This cascades into parsing errors:

  • The opening <strong> tag in the first paragraph never gets properly closed, so all subsequent text ends up bolded.
  • The broken <a> tag causes the first line's content ("Timeline...") to be discarded entirely.

2. 为什么移除转义符就正常?

When you remove the backslash (\) to make it <a href="https://www.reddit.com/...">, you're using standard valid HTML syntax. The Html.fromHtml() parser can correctly parse the tag structure, so the Spannable is generated as expected—no missing lines, no unintended bolding.

3. 后续建议

  • Stick to standard HTML in CDATA: Since CDATA protects your content from XML parsing, you don't need to escape quotes, ampersands, etc., inside it. Just write normal HTML like you would in a web page.
  • Use modern parsing modes (if possible): If your app targets Android N (API 24) or higher, switch to Html.fromHtml(htmlstring, Html.FROM_HTML_MODE_COMPACT) (or other supported modes). The newer parser has better error handling for edge cases like this, though it's still best to use valid HTML to avoid unexpected behavior.

对比示例

错误的strings.xml(导致问题)

<string name="nice_html"> <![CDATA[ <div><p><strong><a href=\"https://www.reddit.com/r/nosleep/comments/3ijnt6/im_a_search_and_rescue_officer_for_the_us_forest/\">Timeline</a> of my other stories separated by company.</strong></p><p><a href=\"https://redd.it/7jmvxo\">This</a> story about smashing modems from <a href=\"/u/devdevo1919\">u/devdevo1919</a> reminded of this little gem when I was a customer service representative at $SecurityCompany. Now before you say “but customer service isn’t IT”, let me explain the position. They <em>called</em> us CSRs, but what we really did was mostly technical support for the residential and small business security systems as well as some customer service functions. We had a separate team for the large businesses.</p></div> ]]> </string>

修正后的strings.xml(恢复正常)

<string name="nice_html"> <![CDATA[ <div><p><strong><a href="https://www.reddit.com/r/nosleep/comments/3ijnt6/im_a_search_and_rescue_officer_for_the_us_forest/">Timeline</a> of my other stories separated by company.</strong></p><p><a href="https://redd.it/7jmvxo">This</a> story about smashing modems from <a href="/u/devdevo1919">u/devdevo1919</a> reminded of this little gem when I was a customer service representative at $SecurityCompany. Now before you say “but customer service isn’t IT”, let me explain the position. They <em>called</em> us CSRs, but what we really did was mostly technical support for the residential and small business security systems as well as some customer service functions. We had a separate team for the large businesses.</p></div> ]]> </string>

你的Activity代码(无需修改,只要strings.xml正确即可)

TextView mylabel = (TextView) findViewById(R.id.mylabel);
String htmlstring = getString(R.string.nice_html);
// For API 24+, use Html.fromHtml(htmlstring, Html.FROM_HTML_MODE_COMPACT)
Spannable spannable = (Spannable) Html.fromHtml(htmlstring);
mylabel.setText(spannable);

内容的提问来源于stack exchange,提问作者sudoExclamationExclamation

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:40:07