プロジェクトのファイルとxmlとリソース
アンドロイド・プロジェクトを作成した時に生成されるのはどのようなファイルだろう?
プロジェクトを作成した時に入力した情報は、どこに保存されているのだろうか?
アンドロイドプロジェクトを構成するファイルについて、大雑把ではあるがまとめてみた。前回までに作成したHelloAndroidプロジェクトのデレクトリ構造は以下のようになっている。
srcデレクトリは説明の必要も無い、javaのソースコードを保存するためのデレクトリである。
Android 2.1と表示されている部分も見てのとおりアンドロイドAPIのjarファイルを指している。
当然、アンドロイドプロッジェクト作成時にビルド・ターゲットの指定を「Android 2.1」以外に指定すれば、この表示名も変更される事になる。アプリケーションの設定情報
アンドロイド・プロジェクトのルートデレクトリには、以下の2つアプリケーションの設定情報を記載したファイルがおかれている。
- AndroidManifest.xml
- default.properties
AndroidManifest.xml
参考までに アンドロイド・プログラミングはじめのいっぽのHelloAndroidプロジェクトのAndroidManifest.xmlの内容を以下に示す。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="xxx.yyy" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".HelloAndroid" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="2" /> </manifest>
めぼしいタグを拾ってみると、
-
manifestタグ
- package属性
アンドロイドプロジェクトの作成時に指定した「パッケージ名」を指している。 - android:versionCode属性
内部のバージョン番号で、ユーザに示すためのものではなく、 ビルド番号などの内部的にプログラムを管理するために使うらしい。 - android:versionName
ユーザに示すためのバージョン番号で、文字列リソースへの参照を設定してもよいそうだ。
リソースへの参照方法については後述する。
- package属性
-
applicationタグ
-
android:label属性
アプリケーションの表示名を示している。
試しに、この値を「abc」と書き換えてプログラムを実行した後で、エミュレータで 「設定」→「アプリケーション」→「アプリケーションの管理」を選択してみると以下のように表示された。
-
android:icon属性
アプリケーション全体に対するアイコン。
アクティビティタグに対しては、また個別にアイコンを設定できる。
drawable リソースに対する参照で設定する必要がある。
-
android:label属性
-
activityタグ
-
android:name属性
アンドロイドプロジェクトの作成時に「Create Activity」欄で指定したActivityクラスのクラス名を指している。 -
android:label属性
アプリケーション名(アンドロイドプロジェクトの作成時に「アプリケーション名」欄で指定した名前)を指している。
試しに、この値を「def」と書き換えてみると以下のように表示された。
-
android:name属性
-
uses-sdkタグ
-
android:minSdkVersion属性
アンドロイドプロジェクトの作成時に指定した「Min SDK Version」を指している。
-
android:minSdkVersion属性
AndroidManifest.xmlに指定するタグの詳細は The AndroidManifest.xml File - Android Developers を参照。
default.properties
HelloAndroidプロジェクトのdefault.propertiesの前半のコメントの部分をのぞいてたものを以下に示す。
# Indicates whether an apk should be generated for each density. split.density=false # Project target. target=android-7
通常のjavaのプロパティファイルである。
内容を変更しないようにとコメントに書かれている。
antでビルドする時に使われるらしい。
最後の行に、プロジェクトの作成時に指定した「ビルド・ターゲット」のAPIバージョンが指定されている。
リソースとRクラスとアセット
resデレクトリとassetsデレクトリは、それぞれリソース(Resources)とアセット(Assets)と呼ばれ、どちらもプログラムの外部データ(ファイル)を保存するために使われる。
ResourcesとAssetsを辞書でひいてみると、それぞれ「財源」と「財産」とある。
どちらも外部データを保存するという意味では同じであるが、データへのアクセス方法が異なる。
リソース
リソースはresデレクトリのサブデレクトリに置かれ、データの種類によって保存するサブデレクトリが決まっている
drawableサブデレクトリには画像ファイルを, layoutサブデレクトリには画面のレイアウト用xmlファイルを, valuesサブデレクトリには文字列や配列、スタイルなどのxmlデータファイルを 保存する決まりになっている。
更に各リソースのサブデレクトリは、アンドロイド・マシーンの環境に応じてより細分化されたサブデレクトリ名となる。
例えば、画像ファイルを保存するdrawableサブデレクトリの場合は、 以下の3つのサブデレクトリに細分化される。
- drawable-ldpi:低密度(ldpi)スクリーン用の画像ファイルを配置するサブデレクトリ
- drawable-mdpi:HVGA(mdpi)の中密度スクリーン用の画像ファイルを配置するサブデレクトリ
- drawable-hdpi:高密度(hdpi)スクリーン用の画像ファイルを配置するサブデレクトリ
マシーンの画面の解像度に応じて最適な画像を使うように、自動的にサブデレクトリの画像ファイルを使い分けるようである。
これらのデータには専用のAPIが用意されていて、簡単にアクセスできるようになっている。
Rクラスとリソース
アンドロイド・プロジェクト作成時にgen [Generated Java Files]デレクトリのパッケージ内にRというクラスが自動生成される。
このファイルは手動で修正を加えてはならない。
以下にRクラスのソースの例を示す。
/* AUTO-GENERATED FILE. DO NOT MODIFY. * * This class was automatically generated by the * aapt tool from the resource data it found. It * should not be modified by hand. */ package xxx.yyy; public final class R { public static final class attr { } public static final class drawable { public static final int icon=0x7f020000; } public static final class id { public static final int textView=0x7f050000; } public static final class layout { public static final int main=0x7f030000; } public static final class string { public static final int app_name=0x7f040000; public static final int hello=0x7f040001; } }
上記のRクラスのソースコードは、レイアウトファイル「main.xml」と文字列リソースファイル「strings.xml」が 以下のように記述されている場合の例である。
main.xml(resデレクトリのlayoutサブデレクトリ)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/textView" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> </LinearLayout>
strings.xml(resデレクトリのvaluesサブデレクトリ)
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Hello, Android</string> <string name="hello">ラベルウィジェット</string> </resources>
resデレクトリ配下のデータファイルに変更を加えると、それに応じてRクラスのjavaコードはecliseのアンドロイドプラグインによって自動的に修正される。
以前、xmlによるGUI画面の定義 をおこなった時に、setContentViewメソッドで引数にR.layout.mainを指定してレイアウト用のxmlファイルを指定した事を思い出してみょう。
以下に、この時のonCreateメソッドのコードを再掲する。public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); }
Rクラスのコードをみると(20行目)、このR.layout.mainという引数はリソースファイルより自動生成されたint型の定数である事がわかる。
また、以下のようなコードで、stringタグ(strings.xml)の文字列リソースを取り出す事もできる。
onCreateメソッドを以下のように変更する。
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tv = new TextView(this); setContentView(tv); String str = getString(R.string.app_name); tv.setText(str); }
main.xmlとstring.xmlというファイル名は、別の名前に変更してもかまわない。
main.xmlのファイル名を例えばsub.xmlに変更した場合には、当然、setContentViewメソッドに渡す引数もR.layout.subに変更する必要がある。
xmlファイルからのリソースの参照
リソースをxml設定ファイルから参照する事もできる。
xml設定ファイルの中に@の付いた属性値が指定されている。
例えば、前掲のAndroidManifest.xmlのapplicationタグのandroid:icon属性には「@drawable/icon」が指定されている。
これはresデレクトリのサブデレクトリdrawable(画面の解像度に応じてデレクトリが3つに分かれている)のicon.pngファイルの画像を使う事を示している。
同様にapplicationタグのandroid:label属性「@string/app_name」は resデレクトリのvaluesサブデレクトリにあるxmlファイルのstringタグで定義されている文字列リソースapp_nameの値を指している。
また、前掲のmain.xmlの6行目のTextViewタグのandroid:text属性「@string/hello」は同様に文字列リソースhelloの値を指している。アンドロイド・プログラミングはじめのいっぽ の xml設定ファイルによる表示文字列の変更 で表示文字列を変更する事ができたのもこの仕組みによる。
xmlレイアウトファイルで定義したウィジェットにコードからアクセスする。
xmlレイアウトファイルで定義したウィジェットをコードからアクセスするには、レイアウトファイルのウィジェット定義にandroid:id属性を指定します。
前掲のmain.xmlのandroid:id属性(6行目)は、「@+id/textView」を指定しています。
この@+id/の後のtextViewの部分が、ウィジェットのidになります。
レイアウトファイルでidを指定すると、前掲のRクラスのソースの例の17行目のように、id(ここではtextView)が定義されます。
このコードから、レイアウトファイルにより生成されたウィジェットにアクセスするには、findViewByIdメソッドの引数にウィジェットのidを指定します。
以下に、xmlレイアウトファイルで定義したウィジェットをコードからアクセスするコードの例を示します。
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView tv = (TextView) findViewById(R.id.textView); tv.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { ((TextView)v).setText("クリックされました"); } }); }
このプログラムでは、レイアウトファイルに定義されたTextViewオブジェクトを取得して、 そのTextViewがクリックされた時に「クリックされました」と表示するonClickイベントメソッドを記述しています。
イベント処理については次回以降に説明します。
アセット
assetsデレクトリに保存された外部データファイルは 、 AssetManager クラスを使ってバイトストリームとしてファイルを読み込みます。アセットにデータを保存して使用するアプリケーションは少ない。
アイコンを自前のものに換えてみる。
3つのdrawableデレクトリのアイコンファイルicon.pngの解像度を調べてみると、 ldpiは36x36ピクセル,mdpiは48x48ピクセル,hdpiは48x48ピクセルであった。
当サイトのトレードマークである「ぼけナス」画像を、フリーの画像編集ソフトを使って 同じピクセル数のpng画像に変換して、「gudon.png」というファイル名で各drawableデレクトリに配置した。
またAndroidManifest.xmlの6行目を以下のように修正。
<application android:icon="@drawable/gudon" android:label="@string/app_name">
プログラムを実行してみると、当然の事であるがアイコンが「ぼけナス」マークに変更された。
リソースとアセットについては、まだまだ触れなければならないさまざまなトピックがあるが、今回はさわりという事でここまでにしたい。
いずれ別の機会にもう少し補足を加えるつもりでいる。