定期処理ハンドラ

サンプルの「Snake」を題材として、アプリ作成の基本をまとめるシリーズです。

第二回目は「定期処理ハンドラ」です。

定期処理ハンドラとは、Handlerクラスを利用して、一定の間隔で処理を行わせる仕組みのことです。

例えば、場面場面でキャラクターの出現数の違いによって、処理の重さが異なる場合があります。
処理の重さの違いでキャラクターの動きにムラは出したくありません。
また、端末の処理能力の違いでキャラクターの動く速度が変わってしまうことも避けたいです。

その解決方法の一つとして、定期処理ハンドラの仕組みがあります。
「Snake」では、以下のように定期処理ハンドラを使用しています。

【SnakeView.java】

class RefreshHandler extends Handler {

@Override
public void handleMessage(Message msg) {
SnakeView.this.update();
SnakeView.this.invalidate();
}

public void sleep(long delayMillis) {
this.removeMessages(0);
sendMessageDelayed(obtainMessage(0), delayMillis);
}
};


public void update() {
if (mMode == RUNNING) {
long now = System.currentTimeMillis();

if (now - mLastMove > mMoveDelay) {
clearTiles();
updateWalls();
updateSnake();
updateApples();
mLastMove = now;
}
mRedrawHandler.sleep(mMoveDelay);
}
}


sendMessageDelayedメソッドによって、指定時間(delayMillis)後にMessageオブジェクトを送信しています。
Messageオブジェクトは、handleMessageオブジェクトで受信されます。
handleMessageオブジェクトから呼び出されるupdateメソッドでsendMessageDelayedメソッドを呼び出しています。
これを繰り返すことで、指定時間(delayMillis)の間隔で定期的な処理を実現しています。

この定期処理の中で、アップデートやViewの再描画を実施しています。
SnakeView.this.update();
SnakeView.this.invalidate();

前回のアップデートからの経過時間が指定時間(mMoveDelay)より大きい場合のみ、アップデートを実施すれば更新間隔を一定に保つことができます。

sendMessageDelayedメソッドによって送信するMessageオブジェクトは、以下のpublicなフィールドを持つMessageクラスのオブジェクトです。

public int what;
public int arg1;
public int arg2;
public Object obj;

フィールドには、sendMessageDelayedメソッドによって引き渡したい値を代入します。
定期処理を実現するだけならば、引き渡す値は何でもかまいません。
「Snake」では、what=0の値を送信しています。


因みに、指定時間(mMoveDelay)は、以下のように初期設定してあります。
mMoveDelay = 600;

アップデート処理の中で、ヘビがリンゴを食べる度に指定時間(mMoveDelay)を減少させています。
mMoveDelay *= 0.9;

次第に定期処理の間隔を短くして、ヘビの動きを速くすることで、ゲームの面白さを実現しています。


最後に、Messageオブジェクトの詳細です。

Messageオブジェクトの作成とフィールド値の設定は以下のようにします。

Message msg = new Message();
msg.what=123;
msg.arg1=1;
msg.arg1=2;
msg.obj="object";

obtainMessageメソッドを利用すれば、以下のように簡単に出来ます。

Message msg = obtainMessage(123,1,2,"object");


obtainMessageメソッドは以下のようにオーバーロードされています。

obtainMessage(int what)
obtainMessage(int what, Object obj)
obtainMessage(int what, int arg1, int arg2)
obtainMessage(int what, int arg1, int arg2, Object obj)


「Snake」では、obtainMessage(int what)でオブジェクトの作成とフィールド値の設定を行っています。

コメント

このブログの人気の投稿

Android SDK アップデート後のエラー対応

プロキシ設定 Android Studio

Avoid object allocations during draw/layout operations (preallocate and reuse instead)