AndroidStudioを使ってハマったので、愚痴がて書き残してみます。
Layout中の idを renameすると、意図しないところまで変わることがある!
たとえば、R.layout.fragment_hoge
の中に R.id.error_text
があったとしましょう。
で、そのうちエラー以外の情報も表示するようになったので、 R.id.message_text
に変えたくなったとします。そんなの AndroidStudioの refactor機能で簡単だもんね、参照してるコード上も自動的に変えてくれるし、とドヤ顔で renameしたりすると..
R.layout.fragment_fuga
の中の error_text
まで message_text
に変わってる! そっちはエラーしか出さないからそのままでいいのに!!
ということになったりします。
ある意味しょうがない
憤慨はしてみたものの、そういう動作になってしまうのもしょうがない一面はあると思います。
なにしろ、Javaソース上で R.id.error_text
という定数があった場合、これが fragment_hoge
の Viewをさしてるか fragment_fuga
の Viewを指してるか一般的に見分ける方法はありません。このコードでは renameに追従するけど、このコードでは fragment_fuga
の Viewを指してるからほっとこう、ということは自動的にはできません。いや、もしかするとそもそも両方の fragmentで同じ idの Viewがあることに依存したコードなのかもしれません。
それを考えるとツールにできる最善のことは、同じ idをつかってる Viewはすべて変更してしまいコードの整合性を保つことかもしれません。やれやれ。
とはいうもののそんな refactoring 役に立つのか?
個人的な感想としては、そんな動作は期待してないことがおおいのではないでしょうか。
そもそも意味的に関連しない部分に同じ idをつけるなよ、というのが正しいのかもしれません。でもそれだったら最初から衝突しないように名前空間を分けられるシステムがあるべきじゃないのかなあ、という気がします。naming conventionとかで衝突しないようにするとかやめてほしいっす。
そういうことで、Androidのリソースの名前空間の愚痴になってしまいました。はい。
あと、ちょっと思いついたのは AARの中の resource idと自分のコードの idが衝突してて、かつ AARの中の resource idを参照してたりする場合どうなるんだろ? さすがに AARの中の jarが参照している idは書き変えられないだろうから、整合性のある renameできない気がしてきた。まあ、AARのなかの idをクライアントから参照することはあんまりなさそうですが。
ということで、使わないほうがいいのかな、という気がします。
せめて衝突してた時は警告してくれるような実装になってないとこわいんじゃないですかね。
まあ、普通に Commitするまえに diffみてれば変なところを変わってるなあ、ってわかるようになるはずだけど、そんなところで手戻りするの面倒です。