Java 的Event机制浅析
来源:互联网 发布:论文数据来源怎么标注 编辑:程序博客网 时间:2024/06/03 20:39
通常java添加监听类似C里面的回调,通常在使用时比较简单,自己定义的事件类(继承EventObject),定义监听
器接口(继承EventListener),定义一个者向量来保存添加的这些监听器,通过addListenerremoveListener来操作。
但是监听器如何被触发的,从底层消息到启动监听器的流程是什么样子的?
将分篇来说明,下面以一个BossXi ,BossLi类来说明:
添加EmployeeEvent事件类:
添加EmployeeListener监听接口:
添加分发消息接口MessageHandler:
添加消息Message类:
添加队列轮询线程PollThread类:
添加EventManager类:
添加EmployeeEventCast类:
添加BossXi ,BossLi 类:
测试代码:
器接口(继承EventListener),定义一个者向量来保存添加的这些监听器,通过addListenerremoveListener来操作。
但是监听器如何被触发的,从底层消息到启动监听器的流程是什么样子的?
将分篇来说明,下面以一个BossXi ,BossLi类来说明:
添加EmployeeEvent事件类:
package Company;import java.util.EventObject;public class EmployeeEvent extends EventObject{private int m_nReason;private int m_nType;private Object m_sSource;public EmployeeEvent(Object arg0,int reason , int type) {super(arg0);// TODO Auto-generated constructor stubthis.setType(type);this.m_nReason = reason;this.m_sSource = arg0;}/** * */private static final long serialVersionUID = 1L;public static final int EVENT_WORK_ON = 0;public static final int EVENT_WORK_OFF = 1;public int getReason(){return m_nReason;}public int getType(){return m_nType;}public int setType(int nType){return this.m_nType = nType;}public Object getSource(){return (java.lang.Object)m_sSource;}}
添加EmployeeListener监听接口:
package Company;// 实现 EventListener接口public interface EmployeeListener extends java.util.EventListener{// 使用监听器的时候,实现并添加到public void onEmPloyeeEvent(EmployeeEvent empEvent);}
添加分发消息接口MessageHandler:
package Company;public interface MessageHandler { public void processMessage(Message message); }
添加消息Message类:
package Company;public class Message { public final static int TerminateType = -1; public int type; public Object data; MessageHandler handler; public Message(MessageHandler p, int t, Object d) { handler = p; type = t; data = d; } public boolean equals(Object o) { Message e = (Message) o; return ((handler == e.handler) && (type == e.type) && data.equals(e.data)); }}
添加队列轮询线程PollThread类:
package Company;import java.util.Vector;public class PollThread extends Thread{private static int nThreadCounts;private static Object syncObj = new Object(); private Vector<Message> messageQueue=new Vector<Message>(); private Object messageSignal=new Object(); protected boolean runing=false; String name; static { setnThreadCounts(0); } public PollThread(String name){ super(name); this.name = name; synchronized(syncObj){ setnThreadCounts(getnThreadCounts() + 1); } }public static int getnThreadCounts() {return nThreadCounts;}public static void setnThreadCounts(int nThreadCounts) {PollThread.nThreadCounts = nThreadCounts;} public void addMessage(Message message){ if(message==null){ return; } synchronized(messageSignal){ messageQueue.add(message); messageSignal.notifyAll(); } } public boolean removeMessage(Message message){ boolean bRet; if(message==null){ return false; } synchronized(messageSignal){ bRet = messageQueue.remove(message); } return bRet; } private Message getMessage(){ Message msg = null; synchronized (messageSignal){ while (messageQueue.size() == 0) {try {messageSignal.wait();} catch (InterruptedException e) {// TODO: handle exceptione.printStackTrace();}}} msg = (Message)messageQueue.get(0);messageQueue.remove(0);return msg; } public synchronized void waitRun(){ while (!runing) {try {this.wait();} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}} } public void run(){Message msg = null;synchronized (this) {runing = true;this.notifyAll();}while (true) {try {msg = getMessage();if (msg != null) {if(msg.handler == null && msg.type == Message.TerminateType && msg.data == messageSignal){ break; } msg.handler.processMessage(msg);}} catch (Exception e) {// TODO: handle exceptionif (true) {e.printStackTrace();}}}}}
添加EventManager类:
package Company;import java.util.Enumeration;import java.util.Vector;public abstract class EventManager implements MessageHandler{protected PollThread pollThread;protected Vector listeners = new Vector();public static int ECASTER_MESSAGE_TYPE;//protected Vector<EmployeeListener> listeners = new Vector<EmployeeListener>();public EventManager(String string) {// TODO Auto-generated method stubpollThread = new PollThread("PollThread" + string);pollThread.start();pollThread.waitRun();}public void addListener(Object oListener){if (oListener == null) {return ;}for (int i = 0; i < listeners.size(); i++) {if(oListener == listeners.get(i)){return ;}}listeners.add(oListener);}public int size(){return listeners.size();}public void removeListener(Object oListener){if (oListener == null) {return ;}listeners.remove(oListener);}public void removeAllListener(){listeners.clear();}public void castEvent(Object event){if (event == null) {return;}Message Msg = new Message(this, ECASTER_MESSAGE_TYPE, event);if(pollThread == null){pollThread = new PollThread("PollThread" + "EventManager");pollThread.start();pollThread.waitRun();}pollThread.addMessage(Msg);}protected abstract void processEvent(Object listener, Object event); // 由该类的继承类实现public void processMessage(Message msg){ Object listener = null; Object event = null; if(msg.type!=ECASTER_MESSAGE_TYPE){ return; } Vector listeners_bak = (Vector)listeners.clone(); event = msg.data; for (Enumeration e = listeners_bak.elements(); e.hasMoreElements();) { listener = e.nextElement(); if (listener == null) {continue;}try {processEvent(listeners_bak, event); // 触发引用上注册的监听器} catch (Exception e2) {// TODO: handle exceptionif (true) {e2.printStackTrace();}}}} }
添加EmployeeEventCast类:
package Company;public class EmployeeEventCast extends EventManager{public EmployeeEventCast(String name) {super(name);// TODO Auto-generated constructor stub}@Overrideprotected void processEvent(Object listener, Object event) {// TODO Auto-generated method stubEmployeeListener slistener = (EmployeeListener)listener;EmployeeEvent eevent = (EmployeeEvent)event;slistener.onEmPloyeeEvent(eevent); // 触发应用注册的监听器}}
添加BossXi ,BossLi 类:
package Company;public class BossXi {EmployeeEventCast eCast;// 代理的方式来处理event消息public void addLister(EmployeeListener eaddpListener) {eCast.addListener(eaddpListener);}public void removeListener(EmployeeListener emoveListener){eCast.removeListener(emoveListener);}// 老板向雇员发消息 , 也即向轮询线程添加消息addMessagepublic void castEventToEmployee(EmployeeEvent event){eCast.castEvent(event);}}
package Company;// 通过继承EventManager,自己来完成消息的添加public class BossLi extends EventManager{public BossLi(String string) {super(string);// TODO Auto-generated constructor stub}@Overrideprotected void processEvent(Object listener, Object event) {// TODO Auto-generated method stubEmployeeListener slistener = (EmployeeListener)listener;EmployeeEvent eevent = (EmployeeEvent)event;slistener.onEmPloyeeEvent(eevent); // 触发应用注册的监听器}public void addLister(EmployeeListener eaddpListener) {super.addListener(eaddpListener);}public void removeListener(EmployeeListener emoveListener){super.removeListener(emoveListener);}// 老板向雇员发消息 , 也即向轮询线程添加消息addMessagepublic void castEventToEmployee(EmployeeEvent event){super.castEvent(event);}}
测试代码:
package Company;public class Test {public static EmployeeListener eListener;public static BossXi bossXi = new BossXi();public static BossLi bossLi = new BossLi("BossLi");public static void main(){// 实现监听器回调eListener = new EmployeeListener() {@Overridepublic void onEmPloyeeEvent(EmployeeEvent empEvent) {// TODO Auto-generated method stubint event = empEvent.getReason();System.out.print("Event is " + "[" + event + "]");switch (event) {case EmployeeEvent.EVENT_WORK_OFF:System.out.print("Boss call me to work off!! ");break;case EmployeeEvent.EVENT_WORK_ON:System.out.print("Boss call me to work on!! ");break;default:break;}}};// 习老板添加监听器bossXi.addLister(eListener);// 上班事件EmployeeEvent eventon = new EmployeeEvent(bossXi ,EmployeeEvent.EVENT_WORK_ON, EventManager.ECASTER_MESSAGE_TYPE);// 下班事件EmployeeEvent eventoff = new EmployeeEvent(bossXi ,EmployeeEvent.EVENT_WORK_OFF, EventManager.ECASTER_MESSAGE_TYPE);// 习老板喊人干活bossXi.eCast.castEvent(eventon);// 习老板喊人干活bossXi.eCast.castEvent(eventoff);bossLi.addListener(eListener);bossLi.castEvent(eventon);bossLi.castEvent(eventoff);}}
应用主要是使用这个BossLi,BossXi 两个类来添加对应时间的监听
PollThread 是一个轮询线程,专门在Message消息队列里面取最新消息,并触发监听器,调用注册的监听回调
轮询线程轮询的是消息队列的消息,消息队列的消息从哪里来,来了之后作什么用?
通过以上例子,
首先,我们姑且把BossLi 或者BossXi成消息产生的源头,通过castEvent --> addMessage 将消息添加到消息队列;
其次,消息和事件之间如何建立联系,上面例子中是在创建一个消息会传入对应的event事件值,并且提供一个包含分发消息hander(此处是继承接口MessageHandler的一个类);
接着,pollThread 将消息队列里面的消息取出来,利用消息里面已有的processMessage方法来来派发event事件
其实我们还可以在BossLi 或者 BossXi 里面添加JNI方法,收到C层的回调时,来向消息队列里面添加消息,然后在转成event
发给应用的监听器,关键是打通JNI和java,能从jni调到java方法。
发给应用的监听器,关键是打通JNI和java,能从jni调到java方法。
0 0
- Java 的Event机制浅析
- 浅析java的反射机制
- magento的event机制
- 浅析Java的异常处理机制
- 有关Java线程机制的浅析
- 浅析Java的垃圾回收机制
- 有关Java线程机制的浅析
- 浅析Java的异常处理机制
- Java的异常处理机制浅析
- Java异常机制的浅析(一)
- 浅析Java反射机制
- Java 反射机制浅析
- Java异常机制浅析
- Java 反射机制浅析
- Java 反射机制浅析
- Java 反射机制浅析
- Java 反射机制浅析
- 浅析java反射机制
- 九度代码1511
- linux中 likely与unlikely
- android百度地图sdk开发异常检查,事件使用
- 一些常用js方法
- Drupal7 SEO优化必备的10个模块
- Java 的Event机制浅析
- 天长地久
- IOS 开发中相机获取图片 不同方向的相机获取不同的图片的实现 ||图片的从新绘图
- test
- ViewFlipper详解
- 在XCode中使用SVN
- (选做)-模板类中使用友元函数
- 大家好、
- .NET程序集强名称签名实践