Android携帯ゲームを作って世界に配信してみよう(番外編) ―― Androidアプリのライフサイクル
●Homeボタンでアプリをバックグラウンドに,再度フォアグラウンドに
アプリの実行中にユーザがHomeボタンを押すと,アプリはバックグランドへ移動します.その後,ユーザが再びアプリのアイコンを押すと,アプリは再度フォアグラウンドに戻ってきます.その流れを以下で説明します.
1)ActivityのonPauseメソッドをコールバック
Homeボタンが押されたら,Android OSは,ActivityのonPauseメソッドをコールバック呼び出しします.このタイミングでやらなくてはいけないことは,バックグラウンドで再生されているBGM音声の中断です(リストI).これを忘れると,アプリがバックグラウンドに移行しても,BGMが鳴り続けるハメになります.
リストI onPauseメソッドが呼び出されたらBGMを中断する(DribbleActivity.javaより抜粋)
@Override protected void onPause() { Log.d("Dribble", "onPause"); Sounds.pauseBgm(); super.onPause(); } |
2)ThreadクラスのInterruptメソッドを呼び出す
Android OSは,実行中のスレッドのThreadクラスのInterruptメソッドを呼び出して,実行中のスレッドに中断要求を行います.ゲーム・ループ・スレッドは,中断要求されたらループを抜け出し,スレッドの処理を完了させます.
ゲームループ内の先頭で,ThreadクラスのisInterruptedメソッドにて,中断要求がなされていないかどうかをチェックします(リストJ).中断要求されている場合は,ループから抜け出します.また,スリープ中に,中断要求された場合は,InterruptedException例外が発生します.この例外をキャッチして,ループから抜け出し,スレッドの処理を完了します.
リストJ ゲーム・ループ内の先頭で中断要求の有無をチェックする(Main.javaより抜粋)
public static void runLoop() { : for (;;) { if (thread.isInterrupted()) { break; } : try { Thread.sleep(towait); } catch (final InterruptedException e) { break; } : } : thread = null; } |
3)ユーザ操作によりonResumeメソッドを呼び出す
ユーザがアプリを再びアプリをフォアグラウンドに移動させたら,Android OSが,ActivityクラスのonResumeメソッドがコールバック呼び出しします.onResumeメソッドをonPauseメソッドに対応させる形で,このタイミングでBGMの再生を再開します(リストK).
リストK onResumeメソッドが呼び出されたらBGMを再開する(DribbleActivity.javaより抜粋)
@Override protected void onResume() { Log.d("Dribble", "onResume"); Sounds.resumeBgm(); super.onResume(); } |
4)ループ・スレッドを再開する
onResumeメソッドが呼び出されたらSurfaceViewのsurfaceCreatedメソッドがコールバックされ,ループ・スレッドを開始して処理を再開します.
この際には,もう一度,新規にスレッドを生成して,ゲーム・ループを再開します.ゲーム・ループ内の処理では,ゲームの状態に依存するデータは一切扱わず,いったんループを抜けてスレッドを終了しても,再開が可能なようにしておく必要があります(リストL,リストM).
リストL SurfaceViewの生成とsurfaceCreatedのコールバック(リストBを再掲)
class DribbleView extends SurfaceView implements SurfaceHolder.Callback { : @Override public void surfaceCreated(SurfaceHolder holder) { Log.d("Dribble", "surfaceCreated"); Main.createThread(this); } : } |
リストM MainクラスのcreateThreadメソッド(リストCとほぼ同じ)
final class Main { public static void createThread(final SurfaceView view) { Main.view = view; if (first) { : // 2回目の呼び出しのためスルーされる } thread = new Thread() { @Override public void run() { Main.runLoop(); } }; thread.start(); } : } |
Activityのライフサイクルはもう少し複雑なものですが,今回はゲームに絞って,重要な点だけをかいつまんで説明しました.詳細を知りたい方は,下記の公式サイトの説明をチェックしてください.
Activities | Android Developers
http://developer.android.com/intl/ja/guide/topics/fundamentals/activities.html
やまだ・もとやす
スパイシーソフト(株) 代表取締役