Smack PacketReader 监听器启动过程分析
2014-11-24 21:24
225 查看
Smack PacketReader 监听器启动过程分析
一、数据进入线程池
newSingleThreadExecutor
创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
PacketReader中的 listenerExecutor就是一个 newSingleThreadExecutor。
listenerExecutor.submit(new ListenerNotification(packet)); //在这里packet 进入线程池,并由ListenerNotification开启监听模式。
通过submit方法,PacketReader 将从xml解析成java对象的packet 封装在 ListenerNotification 中 提交到线程池去执行。
二、线程的执行
ListenerNotification 实现了Runnable接口,进入线程池后做为一个线程被执行。
执行的时候,从connect 成员变量 recvListeners 中读取 ListenerWrapper,并将packet数据交给 notifyListener 执行 。
只要知道 recvListeners 的数据从何而来,就知道 recvListeners 里面有什么数据了。
private class ListenerNotification implements Runnable {
private Packet packet;
public ListenerNotification(Packet packet) {
this.packet = packet;
}
public void run() {
for (ListenerWrapper listenerWrapper : connection.recvListeners.values()) {
listenerWrapper.notifyListener(packet);
}
}
}
三、recvListeners的数据来源
recvListeners 数据添加只有这一处:来自 XmppConnection 的父类 Connect 的 addPacketListener :
在调用 addPacketListener 的时候,实际上参数 packetListener 和 packetFilter 被 ListenerWrapper 封装后存入了 recvListeners中。
public void addPacketListener(PacketListener packetListener, PacketFilter packetFilter) {
if (packetListener == null) {
throw new NullPointerException("Packet listener is null.");
}
ListenerWrapper wrapper = new ListenerWrapper(packetListener, packetFilter);
recvListeners.put(packetListener, wrapper);
}
四、recvListeners的数据什么时候加入
connect.addPacketListener() 方法应该在 connect.setPacket()调用之前调用。
也就是当程序需要通过connect发送数据的时候(比如执行 connect.connect() connect.setPacket()),需要在发送之前设置connect的 packetListener 和 packetFilter 。
下面是 androidpn客户端 用户注册的部分代码:
[java] view
plaincopy
PacketFilter packetFilter = new AndFilter(new PacketIDFilter(registration.getPacketID()), new PacketTypeFilter(IQ.class));
PacketListener packetListener = new PacketListener() {
public void processPacket(Packet packet) {
if (packet instanceof IQ) {
IQ response = (IQ) packet;
if (response.getType() == IQ.Type.ERROR) {
if (!response.getError().toString().contains("409")) {
Log.e(LOGTAG, "Unknown error while registering XMPP account! " + response.getError().getCondition());
}
} else if (response.getType() == IQ.Type.RESULT) {
xmppManager.setUsername(newUsername);
xmppManager.setPassword(newPassword);
Editor editor = sharedPrefs.edit();
editor.putString(Constants.XMPP_USERNAME, newUsername);
editor.putString(Constants.XMPP_PASSWORD, newPassword);
editor.commit();
Log.i(LOGTAG, "Account registered successfully");
xmppManager.runTask();
}
}
}
};
connection.addPacketListener(packetListener, packetFilter);
五、监听机制
只要在调用connect.setPacke等通讯方法的时候,就要先调用 connect.addPacketListener ,将 PacketListener 和 PacketFilter封装在ListenerWrapper中,保存在队列中。
listenerWrapper通过调用 nofityListener() 方法,启动监听事件。
[java] view
plaincopy
protected static class ListenerWrapper {
private PacketListener packetListener;
private PacketFilter packetFilter;
/**
* Create a class which associates a packet filter with a listener.
*
* @param packetListener the packet listener.
* @param packetFilter the associated filter or null if it listen for all packets.
*/
public ListenerWrapper(PacketListener packetListener, PacketFilter packetFilter) {
this.packetListener = packetListener;
this.packetFilter = packetFilter;
}
/**
[java] view
plaincopy
* Notify and process the packet listener if the filter matches the packet.
*
* @param packet the packet which was sent or received.
*/
public void notifyListener(Packet packet) {
if (packetFilter == null || packetFilter.accept(packet)) {
packetListener.processPacket(packet);
}
}
notifyListener()方法调用自己封装的 filter和listener 的方法。
首先检查 packetFilter 并调用 packetFilter.accept()
然后执行packetListener.processPacket()
这两个类和方法都是在第四步设置的,在这里可以定义自己的逻辑处理数据。
总结:
本篇中,通过 packetFilter设置的 PacketTypeFilter 会影响对不同数据的处理。
转:http://blog.csdn.net/teamlet/article/details/25431155
一、数据进入线程池
newSingleThreadExecutor
创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
PacketReader中的 listenerExecutor就是一个 newSingleThreadExecutor。
listenerExecutor.submit(new ListenerNotification(packet)); //在这里packet 进入线程池,并由ListenerNotification开启监听模式。
通过submit方法,PacketReader 将从xml解析成java对象的packet 封装在 ListenerNotification 中 提交到线程池去执行。
二、线程的执行
ListenerNotification 实现了Runnable接口,进入线程池后做为一个线程被执行。
执行的时候,从connect 成员变量 recvListeners 中读取 ListenerWrapper,并将packet数据交给 notifyListener 执行 。
只要知道 recvListeners 的数据从何而来,就知道 recvListeners 里面有什么数据了。
private class ListenerNotification implements Runnable {
private Packet packet;
public ListenerNotification(Packet packet) {
this.packet = packet;
}
public void run() {
for (ListenerWrapper listenerWrapper : connection.recvListeners.values()) {
listenerWrapper.notifyListener(packet);
}
}
}
三、recvListeners的数据来源
recvListeners 数据添加只有这一处:来自 XmppConnection 的父类 Connect 的 addPacketListener :
在调用 addPacketListener 的时候,实际上参数 packetListener 和 packetFilter 被 ListenerWrapper 封装后存入了 recvListeners中。
public void addPacketListener(PacketListener packetListener, PacketFilter packetFilter) {
if (packetListener == null) {
throw new NullPointerException("Packet listener is null.");
}
ListenerWrapper wrapper = new ListenerWrapper(packetListener, packetFilter);
recvListeners.put(packetListener, wrapper);
}
四、recvListeners的数据什么时候加入
connect.addPacketListener() 方法应该在 connect.setPacket()调用之前调用。
也就是当程序需要通过connect发送数据的时候(比如执行 connect.connect() connect.setPacket()),需要在发送之前设置connect的 packetListener 和 packetFilter 。
下面是 androidpn客户端 用户注册的部分代码:
[java] view
plaincopy
PacketFilter packetFilter = new AndFilter(new PacketIDFilter(registration.getPacketID()), new PacketTypeFilter(IQ.class));
PacketListener packetListener = new PacketListener() {
public void processPacket(Packet packet) {
if (packet instanceof IQ) {
IQ response = (IQ) packet;
if (response.getType() == IQ.Type.ERROR) {
if (!response.getError().toString().contains("409")) {
Log.e(LOGTAG, "Unknown error while registering XMPP account! " + response.getError().getCondition());
}
} else if (response.getType() == IQ.Type.RESULT) {
xmppManager.setUsername(newUsername);
xmppManager.setPassword(newPassword);
Editor editor = sharedPrefs.edit();
editor.putString(Constants.XMPP_USERNAME, newUsername);
editor.putString(Constants.XMPP_PASSWORD, newPassword);
editor.commit();
Log.i(LOGTAG, "Account registered successfully");
xmppManager.runTask();
}
}
}
};
connection.addPacketListener(packetListener, packetFilter);
五、监听机制
只要在调用connect.setPacke等通讯方法的时候,就要先调用 connect.addPacketListener ,将 PacketListener 和 PacketFilter封装在ListenerWrapper中,保存在队列中。
listenerWrapper通过调用 nofityListener() 方法,启动监听事件。
[java] view
plaincopy
protected static class ListenerWrapper {
private PacketListener packetListener;
private PacketFilter packetFilter;
/**
* Create a class which associates a packet filter with a listener.
*
* @param packetListener the packet listener.
* @param packetFilter the associated filter or null if it listen for all packets.
*/
public ListenerWrapper(PacketListener packetListener, PacketFilter packetFilter) {
this.packetListener = packetListener;
this.packetFilter = packetFilter;
}
/**
[java] view
plaincopy
* Notify and process the packet listener if the filter matches the packet.
*
* @param packet the packet which was sent or received.
*/
public void notifyListener(Packet packet) {
if (packetFilter == null || packetFilter.accept(packet)) {
packetListener.processPacket(packet);
}
}
notifyListener()方法调用自己封装的 filter和listener 的方法。
首先检查 packetFilter 并调用 packetFilter.accept()
然后执行packetListener.processPacket()
这两个类和方法都是在第四步设置的,在这里可以定义自己的逻辑处理数据。
总结:
本篇中,通过 packetFilter设置的 PacketTypeFilter 会影响对不同数据的处理。
转:http://blog.csdn.net/teamlet/article/details/25431155
相关文章推荐
- Smack PacketReader 监听器启动过程分析
- Smack PacketReader 启动过程分析
- Smack PacketReader 启动过程分析
- Spring Boot启动过程源码分析(二)事件监听器
- 嵌入式uCLinux内核启动过程分析与设计(ZT)
- rh9.0虚拟机dmesg启动过程分析(2)
- linux启动过程分析 -- 参考资料字节小结了一下
- u-boot启动过程分析——基于lpc2210的移植代码
- tomcat 4.1.30启动过程的源码分析
- GRUB启动过程分析 & GRUB 引导程序配置
- 用Bochs学习Minix(2)-启动过程分析
- uClinux 启动过程详细分析
- u-boot启动过程分析——基于lpc2210的移植代码[转]
- Linux启动分析(1)— 总体过程
- rh9.0虚拟机dmesg启动过程分析(1)
- 基于I386的Linux2.4.18启动过程分析
- tomcat 4.1.30启动过程的源码分析
- uClinux 启动过程详细分析
- Tuscany SCA启动过程分析
- Linux启动分析(1)— 总体过程