今天将一个Android App Sky weather应用导入Eclipse,结果出现了不少到红叉叉。一检查发现都是Res文件夹下到文件报错。报错如下:
经过分析在configure.xml, details.xml等文件中报错均发生在@string相关到代码中,于是判断是string.xml文件到错误导致到。进而进行Google,发现问题为:
由于新版的android sdk 采用了 新版的 aapt(Android项目编译器). 编译更严格了.也就是说, 在strings.xml 里面带了 %s 这样的字符串.
于是进一步Google查到相应文章解决该问题,http://be-evil.org/android-multiple-substitutions-specified-in-non-positional-format.html 如下:
Android2.3 SDK编译出现Multiple substitutions specified in non-positional format的分析
作者:朦朧中的罪惡 发布于:2010-12-7 17:59 Tuesday 分类:Android
昨天谷歌正式放出了Android2.3,抱着尝鲜的心态马上更新了ADT和Android SDK,更新后发现自己2.2下编译的很好的项目出现了问题,错误详细内容为:
- error: Multiple substitutions specified in non-positional format; did you mean to add the formatted="false"
attribute?
- error: Unexpected end tag string
文件是我的语言xml文件,具体内容如下:
反复检查后发现是 %s 导致编译失败,
去Google的Android开发者讨论组查看关于这个问题的讨论 后看到了Xavier Ducrohet大神的回复,说这是由于新的SDK采用了新版本的aapt(Android项目编译器),这个版本的aapt编译起来会比老版本更加的严格,然后在Android最新的开发文档的描述String的部分,已经说明了 如何去设置 %s 等符号,下面是文档片段:
If you need to format your strings using String.format(String, Object...) , then you can do so by putting your format arguments in the string resource. For example, with the following resource:
如果你需要使用 String.format(String, Object...) 来格式化你的字符串,你可以把格式化参数放在你的字符串中,参见下面的例子:
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
In this example, the format string has two arguments: %1$s is a string and %2$d is a decimal number. You can format the string with arguements from your application like this:
在这个例子中,这个格式化的字符串有2个参数, %1$s是个字符串 %2$d 是个浮点数,你可以在你的程序中按照下面的方法来根据参数来格式化字符串:
Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
那么根据例子上说的我需要把%s换成%1$s才行了,修改后编译通过,程序成功启动。
问题补充:
有读者问如何在<string></string>中使用%号
有两个办法可供选择
最后稍微延伸一下这个格式化变化的原因: 大神Bob Kerns 觉得当前Java的格式化字符串方式可读性不好(我也有同感),然后就写了篇博文来提出他认为的最好的方式,
http://bobkerns.typepad.com/bob_kerns_thinking/2010/12/dear-java-better-text-formatting-please.html
于是在string.xml中报错行修改为:
<string name="template_user_agent" formatted="false">"%s/%s (Linux; Android)"</string>
所有问题消除。