Android字符串资源格式化参数不匹配:预期1个参数却传入2个
Android字符串资源CDATA中使用格式化占位符导致参数数量不匹配的原因
问题重现
原始正常工作的字符串资源
<string name="calculator_bottom_sheet_body" translatable="false"> <![CDATA[<b>Basic requirements</b><br /><br /> You must be between 18 - 70 in order to proceed: <ul> <li> requirement 1</li> <li> requirement 2</li> <li> requirement 3 and</li> <li> requirement 4</li> </ul> <br /><br /> <b>Money requirement:</b><br /><br /> From €500 to €15.000<br /><br /> <b>Duration:</b><br /><br /> From 6 to 84 months<br /><br /> If you like to continue press the button below.]]> </string>
对应调用代码:
val body = resources.getString(R.string.calculator_bottom_sheet_body)
修改后报错的场景
将金额行改为带格式化占位符的内容:
From €%s to €%s<br /><br />
调用代码传入两个参数:
val body = resources.getString(R.string.calculator_bottom_sheet_body, minAmount, maxAmount)
抛出错误:
Wrong argument count, format string calculator_bottom_sheet_body requires 1 but format call supplies 2
问题原因
Android的资源编译器(aapt)在解析字符串资源时,不会穿透CDATA块识别内部的格式化占位符(%s)。CDATA的核心作用是让XML解析器将内部内容视为纯文本,跳过所有XML解析操作,这也包含了资源系统对格式化占位符数量的统计逻辑。
当你在CDATA内部添加两个%s占位符时,编译器无法正确统计到这两个占位符的存在,反而会因字符串中存在未被识别的%符号,错误判定该字符串仅需1个格式化参数,最终导致传入2个参数时出现数量不匹配的错误。
解决方法
有两种常用的修复方式:
- 将占位符移出CDATA块:把需要动态替换的部分拆分到CDATA外部,通过XML拼接组合字符串,示例:
<string name="calculator_bottom_sheet_body" translatable="false"> <![CDATA[<b>Basic requirements</b><br /><br /> You must be between 18 - 70 in order to proceed: <ul> <li> requirement 1</li> <li> requirement 2</li> <li> requirement 3 and</li> <li> requirement 4</li> </ul> <br /><br /> <b>Money requirement:</b><br /><br /> From €]]>%1$s<![CDATA[ to €]]>%2$s<![CDATA[<br /><br /> <b>Duration:</b><br /><br /> From 6 to 84 months<br /><br /> If you like to continue press the button below.]]> </string>
- 手动执行字符串格式化:先获取完整的CDATA字符串,再用
String.format()手动替换占位符,示例:
val rawBody = resources.getString(R.string.calculator_bottom_sheet_body) val body = String.format(rawBody, minAmount, maxAmount)
内容的提问来源于stack exchange,提问作者james04
相关产品推荐
相关产品推荐

