自動生成される「gen」フォルダ内の「R.java」について

新卒から、「gen」フォルダ内の「R.java」って何を定義してるの? とか
何であるの? みたいな質問をされたので、30分ほどかけてメールを返信した。
もしかしたら普通にわからないのかな、と思ったのでこちらでも軽く展開。

      • -


「gen」フォルダは「res」フォルダ内の内容をプリコンパイルすることで
自動的に生成され、内部に「R.java」のファイルを生成します。

※「res/drawable」などに画像ファイルを組み込んだりすると勝手に内容が更新されるかと
 思いますが、これはEclipseの「Project→Build Automatically」にチェックが入って
 いるため、ファイルの追加や更新が行われるたびにプログラムがコンパイルされているからです。


これが生成されることによって、例えば「btn_01.png」というファイルを
drawableフォルダに追加したときに「R.drawable.btn_01」と言う指定で
ファイルを指定することが出来るようになります。


例えば文字列であっても、「values/string.xml」に「title_btn_01」といった
要素を追加して、valueに「開始」と指定して保存した場合に、
「R.string.title_btn_01」と指定することが出来るようになります。



特にR.javaファイルの内容を覚える必要はありません。
各要素に設定されている「0x7f020000」などの値はAndroid SDK
コンパイラがそれぞれの要素を判別するための識別値です。


これが生成される利点ですが、まだ使ったことが無い機能になるので
ピンと来ないかもしれませんが指定する際にlocaleや端末の画面解像度を
意識しないでよくなる、と言ったものがあります。



◆ 端末の解像度を自動判別


端末の画像解像度についてですが、例えば「R.drawable.icon」で
最初から入っているiconファイルを指定できると思いますが、この画像は
「drawable-hdpi」「drawable-mdpi」「drawable-ldpi」など複数の
フォルダに保存されていると思います。
では、この「R.drawable.icon」を指定したときにどのファイルが
呼び出されるか、と言うことです。


Androidの端末は、それぞれのハードウェア仕様として
high/middle/low などのdpi(解像度)になっています。最近の端末は、大抵h-dpiですが。


例えば複数の仕様が異なる端末でもレイアウトが崩れないようにしたい場合、
(Galaxy-TabやHTC-Ariaなど) drawableフォルダを分けて画像を配置することで
端末によって表示される画像を変更することが出来ます。


本来であれば、各画像表示を行う前にif文などで解像度によって
表示される画像を切り替えなければいけないところですが、
このR.javaに自動生成される定義値を利用することでコード内では意識せずに
ファイルを切り替えることが可能です。

※drawableフォルダの命名規則などは下記参照 
http://d.hatena.ne.jp/hyoromo/20101118


◆ locale(言語設定)に関して


実はこちらもdrawableフォルダと同様に、フォルダの名称を指定することで
自動的に参照するアイテムを切り替えることが出来ます。


標準では「values」しかありませんが、「values-ja」と言うフォルダを作ると
「日本語のときはvalues-ja内のリソースを参照し、それ以外はvaluesの内容を
参照する」と言ったことが可能になります。


これがどういった意味合いを持つか、と言うことですが
例えば「values-ja/string.xml」で「title_btn_01」に対して「開始」という文字列を指定します。
そして「values/string.xml」では「title_btn_01」に対して「START」という文字列を指定します。


これによって、アプリケーションを開始するボタンを作った場合に
layoutファイル内でButtonのandroid:textに「@string/title_btn_01」を
指定すると日本では「開始」、それ以外の他国では「START」と表示されることになります。



こういった多様なAndroid端末、言語への対応を簡単にする、と言うのも
R.javaファイルの定義が存在する意味合いになります。

      • -

みたいな返信をして、疲れた。