• スポンサードリンク

リソース文字列に書式文字列を入れたら少しハマった

Android

Androidのリソース文字列に書式文字列を割り当てようとしたら少しハマってしまった。
何にハマったかというと、リソース文字列に書式文字列を入れていると、eclipseのリソースエディタにはエラー表示が無くても実際にはエラーでリソースを生成出来ないことがあるってことです。

おさらい

リソース文字列では次のようにして書式文字列を含むことが出来ます。

これから数字を代入した文字列を取得するには例えば次のようにします。

すると、「人参を3本買った。」という文字列を取得できます。
ここまでは常識ですよね。

では書式文字列を2つ含む場合はというと、

で行けそうな気がしますが、リソース文字列の場合には書式文字列に引数の順番をしていないとリソースのコンパイル時にエラーとなります(昔からエラーになっていたのかは記憶に無いですが)。
なので、引数の順番を指定して、

のようにすれば大丈夫です。
ちなみに、プログラム内でFormatter#formatを呼ぶ出す時には引数の順番をしてしていなくても、前から順に並んでいるものとみなされてエラーにはなりません。
ここまでも特に問題無いですよね。

問題発生するパターン

ところが、多言語対応させようとして、同じid(name)のリソース文字列を定義すると、引数の順番を指定しなくてもエラーが表示されない時があるのです。

例えば、res/values/string.xmlとres/values-ja/string.xmlの2つのファイルを作ってそれぞれに、

res/values/string.xml

res/values-ja/string.xml

のように定義したとすると、eclipseのリソースエディタにはエラーが表示されないのです。
(ここでは2つ目の書式文字列に引数の順番を指定し忘れたことにしています)
でもリソースファイルは生成できないのでリソースへアクセスしているコードにはエラー出まくりです。
もちろん実行できません。どこが悪いかわからへんのに実行できへんのでちょい焦ります。辛うじてError logに
“Caused by: java.io.FileNotFoundException: /プロジェクトのパス名/bin/resources.ap_ does not exist…”てのが出力されます。

そこで、どんなタイミングでエラーチェックをすり抜けてしまうのか色々確認してみました。
その結果、

  1. 同じnameのリソース文字列を定義してない時には、書式文字列の引数の順番を指定しなければエラーとして表示される
  2. 多言語対応のために同じnameのリソース文字列を定義してても、書式文字列の引数の順番を指定しないないのが1つだけだあればエラーとして表示される
  3. 多言語対応のために同じnameのリソース文字列を定義していて、書式文字列の引数の順番を複数の場所で指定し忘れているとエラーとして表示されない

ということみたいです。
リソース文字列に書式文字列を含める場合には、引数の順番を指定し忘れないように十分注意しましょうってことですね。

大したことでは無いけど久しぶりに遭遇したのでちょっとハマってしまいました。
ということで、おしまい。お疲れ様でした。

« »

  • スポンサードリンク

%d人のブロガーが「いいね」をつけました。