读 Beginning Android Games 2nd Edition (六) 创建键盘事件处理类
来源:互联网 发布:java 短信验证码校验 编辑:程序博客网 时间:2024/04/30 02:59
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).这时池(Pool)里还没有任何东西.所以我们创建一个KeyEvent的实例(KeyEvent1)并插入到keyEventsBuffer list中
UI thread: onKey() ->
keyEvents = { }, keyEventsBuffer = {KeyEvent1}, pool = { }
第二步:我们调用主线程中的getKeyEvents方法,getKeyEvents方法从keyEventsBuffer list中拿到实例KeyEvent1,并把它插入到keyEvents
list 并把它返回给调用者
Main thread: getKeyEvents() ->
keyEvents = {KeyEvent1}, keyEventsBuffer = { }, pool { }
第三步:我们从UI线程中得到另一个事件,在池中仍然没有东西.因此一个新的KeyEvent实例被创建并插入到keyEventsBuffer list中
UI thread: onKey() ->
keyEvents = {KeyEvent1}, keyEventsBuffer = {KeyEvent2}, pool { }
第四步:主线程再次调用getKeyEvents方法,有趣的事发生了! keyEvents list 仍然保有KeyEvent1实例,介入的循环将把这个事件放入我们的池中,
之后我们清理掉 keyEvents list,然后插入任何的keyEvent实例到keyEventsBuffer,在这种情况下,KeyEvent2就是我们可以反复利用的Key事件
Main thread: getKeyEvents() ->
keyEvents = {KeyEvent2}, keyEventsBuffer = { }, pool = {KeyEvent1}
第五步:另一个Key事件到达UI线程,这次我们在池中free拿到KeyEvent,重复利用这个对象,避免了垃圾回收
UI thread: onKey() ->
keyEvents = {KeyEvent2}, keyEventsBuffer = {KeyEvent1}, pool = { }
- 读 Beginning Android Games 2nd Edition (六) 创建键盘事件处理类
- 读 Beginning Android Games 2nd Edition (七) 创建Touch事件处理类
- 读 Beginning Android Games 2nd Edition (八) 创建输入事件处理类
- 读 Beginning Android Games 2nd Edition (三) 创建速度感应器事件监听类
- 读 Beginning Android Games 2nd Edition (四) 创建罗盘事件监听类
- 读 Beginning Android Games 2nd Edition (一) 创建读取文件IO的工具类
- 读 Beginning Android Games 2nd Edition (二) 创建声音工具类
- 读 Beginning Android Games 2nd Edition (五) 创建对象池类
- 读 Beginning Android Games 2nd Edition (九) 创建像素图类
- 读 Beginning Android Games 2nd Edition (十) 创建绘图类
- 读 Beginning Android Games 2nd Edition (十六) 游戏帮助
- 读 Beginning Android Games 2nd Edition (十八) 贪食蛇类
- 读 Beginning Android Games 2nd Edition (十二) 把框架基础功能放入Game类中
- 读 Beginning Android Games 2nd Edition (十四) 玩家设置存储类
- 读 Beginning Android Games 2nd Edition (十七) 分数榜类
- 读 Beginning Android Games 2nd Edition (十九) 游戏World类
- 读 Beginning Android Games 2nd Edition (二十) 游戏GameScreen类
- 读 Beginning Android Games 2nd Edition (二十一) 封装OpenGL之GLGraphics类
- VS2010+OpenCV2.4.3+Qt4.8.4 组合配置
- Tomcat详解 二
- 好想毕业出去了,在学校真累
- HTTP协议详解
- “当前不会命中断点 还没有为该文档加载任何符号”解决方法
- 读 Beginning Android Games 2nd Edition (六) 创建键盘事件处理类
- 移植Java虚拟机到mini2440
- adb devices no permissions 解决办法
- 第2章:将摄氏温度转换为华氏温度
- RFC0959---FTP协议
- JQuery学习(一)
- curl应用总结
- javascript事件冒泡与事件捕获
- nginx下 499错误