Androidアプリ/日記4
ActivityとかViewって何だろう?
前回、プロジェクトを新規に生成したときにでてきた「Activity」とか、「View」とかっていう概念のおさらいをしないまま前に進んでいくと何だか危険そうなので、調べて整理してみました。
Activityって何だろう?
Activityというのは、その名の通りアプリが行う活動のことです。計算機アプリであればその活動は「計算」です。電卓のどのボタンが押されたかを判別して、「+」ボタンなら加算して、答えを計算するのがActivityの内容です。Windowsでいうところのプロセスみたいなものだと思えばいいと思います。
今回作成する体重管理アプリの場合は「体重を管理する」ことがActivityの内容となります。ただ、管理すると一言で片づけてしまってはあまりに抽象的ですので、「Androidアプリ/日記2」で行ったときのようにActivityの設計も後で行う必要がありそうです。
ActivityがGUIを持つ場合、そのActivityは後述の「View」をもつことになります。せっかくタッチパネルのついた携帯端末を持っているのですから、いろいろと画面をタッチしたりフリックしたりして、直感的な操作を楽しみたいのでViewを持たせる方が楽しそうですが、Viewを必要としないActivityだってきっといろいろあるんでしょうね。WEBをひたすらクロールして、欲しい情報を蓄積するActivityとか、動画を変換し続けるだけのActivityとか、各種サーバActivityとか・・・。
先ほど、ActivityをWindowsのプロセスに例えましたが、プロセス同様にActivityには始期と終期があります。アプリを起動すると最初のActivityが呼び出されますが、これがActivityの始期です。またActivityが別のActivityを呼び出すこともあります。これもActivityの始期です。
明示的にActivityが終了させられたときにActivityの終期が訪れます。設定画面のアクティビティなどは、数値を選択して元の画面に数値を引渡したらお役御免ですので、明示的に終了させますね。それとは別にAndroidはマルチタスクなOSですので、アプリAを開いている状態で別途アプリBを開くなんてことができますが、新しいアプリを開くたびに限られたメモリの使用量が増すわけですから、無限にアプリを開くわけにはいきません。そこでAndroidは裏に回ったActivityをメモリの使用状況を見つつ殺していきます。そのときにもActivityの終期が訪れるわけですね。ユーザとしては、メモリ管理を意識せずともアプリをいくらでも好きな時に開けるので使い勝手がよいのですが、開発者はActivityの終期を意識してアプリ開発を行わないといけないそうです。編集中のアプリ内の大事なデータを保存前にActivityごと消えてしまうことがないように気をつけないとですね。
Acitivityの始期と終期の話をしたついでに、Activityには画面上に表示されている時期、画面の最前面でまさに操作されている時期があることも書いておきましょう。Windowsでいうところのウィンドウが表示されている状態とアクティブ(ファーカスがある)な状態のことですね。Acitivityがどんな状態に遷移したら、どんな処理が必要であるか、ということを意識しておくとよいそうです。
Activityの開始時期(onCreate)
Activityの描画対象時期(onStart)
Activityの操作対象時期(onResume)
Activityが操作対象から外れる(onPause)
Activityが描画対象から外れる(onStop)
Activityの終了時期(onDestroy)
()の中にはそれぞれのタイミングで呼び出されるメソッド名を書いておきました。画面内の情報を後に引き継ぎたい場合は、操作対象から外れたonPauseのタイミングで画面内の情報を保存する処理を行い、改めて表示されたタイミングで情報を復旧してあげるといいでしょう。
上には書いてありませんが、ActivityがonPauseした後、OSから消される前に改めて呼び出されるとonRestartというメソッドが呼び出されるそうです。Activityのライフサイクルに関するメソッドはそのくらいかな・・・。
Activityの目的に応じて、どのタイミングで何をさせるのかはいろいろ変わってきそうですね。
Viewって何だろう?
GUIを持つActivityの画面を描画する部位がViewです。Windowsでいうところのウィンドウですね。Viewのレイアウトはres/layoutの中のXMLファイルで定義されます。このXMLの書式については後で勉強しながら書いてみましょう。ボタンやテキスト入力欄などもViewのクラスを継承していて、Viewの中で入れ子になって配置できるようになっています。
Activityのソースファイルを眺めてみると、
setContentView(R.layout.main);
といった形でViewを定義するlayoutデータ(R.layout.main)が指定されていました。Rはリソースを定義するために自動的に生成されるクラスですね。res/layout/main.xmlのXMLファイルを示すint値がR.layout.mainに定義されているようです。
どんなActivityが必要なんだろう?
Activityのことをおさらいしたところで、実際にどんなActivityがアプリに必要なのか検討してみたいと思います。既に日記2で画面の設計をしています。
- タイトル画面
- 体重入力画面
- グラフ出力画面
- ユーティリティ画面
この4画面をそれぞれViewとして定義するとなると、Activityもそれぞれ4つ設ければよさそうです。さしあたって、プロジェクト生成時に一緒に生成されたActivity「ManageWeight」をタイトル画面として作り込んでいこうと思います。その他の3つの画面用のActivityも用意してあげましょう。
画面 | Activity | View設定ファイル |
タイトル画面 | ManageWeight | main.xml |
体重入力画面 | InputWeight | input.xml |
グラフ出力画面 | GraphWeight | graph.xml |
ユーティリティ画面 | UtilWeight | util.xml |
Activityを定義するソースファイルはeclipseのPackage Explorer上で右クリックして「New」→「Class」でクラスの追加ダイアログを開きます。Activityクラスを継承させて上記のような名前で各画面用のActivityのサブクラスを追加します。
Viewを定義するXMLファイルは同様に「New」→「Android XML File」からアプリのリソース定義ダイアログを呼び出して追加できました。上記のファイル名でリソースの種別を「Layout」として「Finish」ボタンを押すと新しいファイルが追加されます。余談ですが、機種や言語、地域によってリソースを分ける場合もこのダイアログ上で簡単にFolder分けができそうですね。また、XMLのルート要素も選択できるみたいですね。とりあえず、標準のLinearLayoutが選択された状態でレイアウトファイルを追加しました。
続いて、eclipseのAndroidManifest.xml編集画面からActivityを定義してみます。
AndroidManifest.xml編集画面の「Application」タブを開くと「Application Nodes」という欄があり、現在設定されているActivityが一覧されています。横の「Add...」ボタンをクリックすると新しいActivityを追加するためのダイアログが開きました。「Create a new element at the top level, in Application」を選択して、追加項目の一覧から「Activity」を選択し、「OK」ボタンを押すと新しい無名のActivityが追加されました。
その後、追加されたActivityを選択すると、右側でActivityの詳細を変更できるようです。「Name」と「Label」をそれぞれ設定しました。「Label」には自動的に作られた「ManageWeight」に倣って「@string/app_name」と入れておきましたが、これはres/values/strings.xmlで定義されている「app_name」の値が入ることになります。このLabelの値が何に使われるのか、現時点でちゃんと理解していません。
それぞれのActivity中でどのViewを使うのか紐づいていないので、最初に生成されたManageWeight.javaファイルに倣って以下のようなメソッドをそれぞれのActivityに追加しました。layout名は適宜変えてあります。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
onCreateはActivityの生成時に呼び出されるメソッドでしたね。スーパークラスの同名メソッドを呼び出して、その後レイアウトをsetContentViewメソッドで決定しています。
次回以降、順番にActivityの実装を進めていきましょう。