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

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个参数时出现数量不匹配的错误。

解决方法

有两种常用的修复方式:

  1. 将占位符移出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>
  1. 手动执行字符串格式化:先获取完整的CDATA字符串,再用String.format()手动替换占位符,示例:
val rawBody = resources.getString(R.string.calculator_bottom_sheet_body)
val body = String.format(rawBody, minAmount, maxAmount)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 16:55:32