世界を目指せ!Androidアプリ開発入門

第4回Androidの肝、アクティビティ

前回のおさらい

前回は、サンプルプログラム「SkeletonApp」をビルドして、エミュレーターと実機で動作確認を行い、エミュレータと実機では操作感が違うことをご説明しました。

今回は、Androidの肝でもあるアクティビティを取り上げます。

アクティビティとは?

アクティビティは、Androidの画面に相当し、ユーザが操作する画面と操作に対する処理を行います。画面を持つ物はアプリは、必ずアクティビティを持ちます。

これを「Windowsで例えると○×です」と言えれば、話しが早いのですが、Windowsには似たオブジェクトが存在しません。たとえば、同じ画面に相当するウィンドウと比較すると、以下の違いがあります。

  • 状況に応じて分岐する遷移状態を持つ
  • インスタンスの保存・復帰する仕組みを持つ
  • Android OSのタイミングで、強制終了・再起動される

少々難解な存在ですが、Androidのアプリ開発では、アクティビティに対する理解が肝になるので、動きや役割をこれからご紹介するサンプルプログラムを使ってしっかりと理解して下さい。

アクティビティとの付き合い方

まずは、以下の状態遷移図を参照して下さい。

どんな処理でも、開始があって終了まで状態遷移するワケなんですが、アクティビティでの状態遷移は少し複雑です。

図1 状態遷移図
図1 状態遷移図

開始から終了まで分岐なしに遷移すれば、面倒な話しはありませんが、ハードリソースを上手く使うために採用された仕組みが、遷移を複雑にしています。

たとえば、アクティビティがonPause, onStopの状態で、他のアプリが大量にメモリを要求すると、Android OSがアクティビティが強制終了します(再呼び出しされると、onCreateからの実行になります⁠⁠。

また、アクティビティがonStopの状態になったらリソースを解放し、アクティビティが前面に移動しonRestartが呼ばれたら、リソース再確保を行うなど、行儀の良いアプリを開発することもできます。

こうした仕組みは、Windowsアプリを開発する感覚だと、難しいと感じるかもしれませんが、アクティビティに対する理解は、今後の開発の基礎となる部分なので、自身で試行錯誤するなどもして、必ず理解して見つけるようにしてください。

サンプルアプルを修正する

では、アクティビティの遷移を確認するために、前回ビルドしたアプリに手を加えていきます。

アクティビティの動きを確認するために、Dalvik Debug Monitor(以下、ddmsとします)を使います。ddmsは、SDKフォルダ以下のToolsフォルダに収録されているので、ダブルクリックで起動します(Windowsは、ddms.batです⁠⁠。

図2 ddmsを起動した様子。3ペインに分割された内、画面下のLogタブにデバッグメッセージが出力される。
図2 ddmsを起動した様子。3ペインに分割された内、画面下のLogタブにデバッグメッセージが出力される。

ddmsは、名前の通りアプリのデバッグに活用できます。

ソースコードに、以下のコードを追加すると、ddmsのログウィンドウにデバッグメッセージを表示します。

Log.d( "SkeletonActivity", "onPause" );

デバッグメッセージの表示以外にも、Android OSが出力するエラーメッセージが表示されます。開発中のアプリが異常終了したときもメッセージが残るので、問題解決の手がかりを掴むヒントにもなります。このように、ddmsは、アプリ開発には必須ツールなので、この機会に使い方を覚えてください。

それでは、onPause, onResumeの動きを確認します。

Eclipseを起動して、パッケージエクスプローラーのSkeletonActivityからSkeletonActivity.javaを選択して、以下のコードを書き加えます。onPauseは、存在しないコードなので、各自追加してください。

    @Override
protected void onResume() {
    super.onResume();

    Log.d( "SkeletonActivity", "onResume" );
}

@Override
protected void onPause() {
    super.onPause();

    Log.d( "SkeletonActivity", "onPause" );
}

コードを追加すると、Logクラスをインポートしないとエラーとなるので、以下のクラスをインポートするようにして下さい。

#import android.util.Log;

それでは、エミュレータを使って動作を確認してみます。

アプリを起動すると、ddmsを起動するとログウィンドウに、以下のメッセージが表示されていることを確認してください。

図3 ログウィンドウにメッセージが表示される。
図3 ログウィンドウにメッセージが表示される。

ddmsのログウィンドウには、Android OSが出力するメッセージも含まれており、SkeletonActivityが出力したメッセージを探すのが面倒なので、メッセージをフィルターする機能を使って、表示メッセージを絞り込みます。

図4 フィルターの追加は、画面下のログペインの「+」をクリックする。⁠by Log Tag]には、コードで指定したTagを指定する。
図4 フィルターの追加は、画面下のログペインの「+」をクリックする。[by Log Tag]には、コードで指定したTagを指定する。

ddmsを使って動きを確認する

ddmsのログウィンドウには、"onResume"のメッセージが表示されて、アクティビティがonResumeのイベントを受け取って、実行されたことが確認できます。アクティビティが前面で動作していると、状態遷移図の「アクティビティ実行中」のところにあります。

では、この状態でホームボタンを押してください。すると、ddmsのログウィンドウには"onPause"のメッセージが表示され、状態遷移図の「onPause」に遷移したことが確認できます。この状態で、ホーム画面からSkeletonActivityをタップして起動すると、また、ddmsのログウィンドウに"onResume"と表示され「onResume」を通過し、再度「アクティビティ実行中」の状態になったことが確認できます。

少し複雑な遷移をしましたが、これは序の口です。

アクティビティが裏に周り「onPause」の状態で、他のアプリから大量のメモリが要求されると、Android OSが背面のアクティビティを強制終了する可能性があります。強制終了したアクティビティが復帰の時は「onResume」からではなく「onCreate」からとなり、一から起動された場合と同じ遷移になります。これ、アプリを開発するうえでは、大きなポイントになります。

リソース管理のコツは?

アクティビティが使うリソースは、この遷移を理解したうえで管理する必要があります。

アプリよって、リソースの管理方法は変わりますが、筆者が開発に関わっているNetaShareでは、

  • 1画面、1アクティビティとする
  • 強制終了される前提でリソースを扱う
  • アクティビティを跨いでリソースを使用しない

を心がけています。

筆者の経験では、この3点を心がけることで、アプリの実装がスッキリする印象を持っています。

T-mobile G1のようなハードキーボードを搭載した機種では、キーボードの開閉でアクティビティの再起動が行われます。日本には、ハードキーボードが搭載された端末が存在しませんが、世界を目指すためには、配慮が必要です。頭に入れておいて下さい。

次回は

Android OSには、アクティビティの強制終了に備えて、保持するデータを復帰する仕組みやアクティビティ間でデータをやり取りする仕組みが用意されています。この辺りを上手く使えば、無理なく効率良くアプリを実装できるので、次回、この内容を紹介します。

おすすめ記事

記事・ニュース一覧