Beginning Android Games 2 nd Edition(6)を読んでキーボードイベント処理クラスを作成
3778 ワード
package com.badlogic.androidgames.framework.impl;
import java.util.ArrayList;
import java.util.List;
import android.view.View;
import android.view.View.OnKeyListener;
import com.badlogic.androidgames.framework.Input.KeyEvent;
import com.badlogic.androidgames.framework.Pool;
import com.badlogic.androidgames.framework.Pool.PoolObjectFactory;
public class KeyboardHandler implements OnKeyListener {
boolean[] pressedKeys = new boolean[128]; // , /
Pool<KeyEvent> keyEventPool;
List<KeyEvent> keyEventsBuffer = new ArrayList<KeyEvent>();
List<KeyEvent> keyEvents = new ArrayList<KeyEvent>();
public KeyboardHandler(View view) {
PoolObjectFactory<KeyEvent> factory = new PoolObjectFactory<KeyEvent>() {
public KeyEvent createObject() {
return new KeyEvent();
}
};
keyEventPool = new Pool<KeyEvent>(factory, 100);
view.setOnKeyListener(this);
view.setFocusableInTouchMode(true);
view.requestFocus();
}
public boolean onKey(View v, int keyCode, android.view.KeyEvent event) {
if (event.getAction() == android.view.KeyEvent.ACTION_MULTIPLE)
return false;
synchronized (this) {
KeyEvent keyEvent = keyEventPool.newObject();
keyEvent.keyCode = keyCode;
keyEvent.keyChar = (char) event.getUnicodeChar();
if (event.getAction() == android.view.KeyEvent.ACTION_DOWN) {
keyEvent.type = KeyEvent.KEY_DOWN;
if(keyCode > 0 && keyCode < 127)
pressedKeys[keyCode] = true;
}
if (event.getAction() == android.view.KeyEvent.ACTION_UP) {
keyEvent.type = KeyEvent.KEY_UP;
if(keyCode > 0 && keyCode < 127)
pressedKeys[keyCode] = false;
}
keyEventsBuffer.add(keyEvent);
}
return false;
}
public boolean isKeyPressed(int keyCode) {
if (keyCode < 0 || keyCode > 127)
return false;
return pressedKeys[keyCode];
}
public List<KeyEvent> getKeyEvents() {
synchronized (this) {
int len = keyEvents.size();
for (int i = 0; i < len; i++) {
keyEventPool.free(keyEvents.get(i));
}
keyEvents.clear();
keyEvents.addAll(keyEventsBuffer);
keyEventsBuffer.clear();
return keyEvents;
}
}
}
このクラスは、前の記事のオブジェクトプールクラスを使用して、KeyEventインスタンスをキャッシュします.
クラスの実行手順は図で説明できます.
第一歩:UIスレッドから新しいイベント(event)を得る.この時プールにはまだ何もありませんでした.そこで、KeyEventのインスタンス(KeyEvent 1)を作成し、keyEventsBufferリストに挿入します.
UI thread: onKey() ->
keyEvents = { }, keyEventsBuffer = {KeyEvent1}, pool = { }
ステップ2:メインスレッドのgetKeyEventsメソッドを呼び出します.getKeyEventsメソッドはkeyEventsBuffer listからインスタンスKeyEvent 1を取得し、keyEvents listに挿入して呼び出します.
ステップ3:UIスレッドから別のイベントを取得し、プールにはまだ何もありません.したがって、新しいKeyEventインスタンスが作成され、keyEventsBufferリストに挿入されますUI thread:onKey()->keyEvents={KeyEvent 1}、keyEventsBuffer={KeyEvent 2}、pool{}
ステップ4:メインスレッドがgetKeyEventsメソッドを再び呼び出し、面白いことが起こりました!keyEvents listはKeyEvent 1のインスタンスを保持しており、介入のループはこのイベントをプールに入れます.
その後、keyEventsリストをクリーンアップし、keyEventインスタンスをkeyEventsBufferに挿入します.この場合、KeyEvent 2は私たちが繰り返し利用できるKeyイベントです.
Main thread: getKeyEvents() -> keyEvents = {KeyEvent2}, keyEventsBuffer = { }, pool = {KeyEvent1}
ステップ5:もう一つのKeyイベントがUIスレッドに到達し、今回はプールでfreeでKey Eventを入手し、このオブジェクトを再利用し、ゴミ回収を回避しました.
UI thread: onKey() -> keyEvents = {KeyEvent2}, keyEventsBuffer = {KeyEvent1}, pool = { }