用smack作一個xmpp客戶端彷佛是一件很簡單的事情。可是前幾天發現的一個bug,仍是讓我思考了不少。java
用smack創建一個xmpp connection。而後在connection 上註冊了一個PacketListener。app
可是程序裏面在一個for循環裏面去new PakcetListener,並把listener註冊到connection上面。這樣致使的結果就是this
smack客戶端收到許多相同的IQ response。code
若是稍微看一下smack的源代碼就明白問題出在哪裏。it
smack connection class:io
/** * Registers a packet listener with this connection. A packet filter determines * which packets will be delivered to the listener. If the same packet listener * is added again with a different filter, only the new filter will be used. * * @param packetListener the packet listener to notify of new received packets. * @param packetFilter the packet filter to use. */ 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); }
/** * List of PacketListeners that will be notified when a new packet was received. */ protected final Map<PacketListener, ListenerWrapper> recvListeners = new ConcurrentHashMap<PacketListener, ListenerWrapper>();
看完上面這兩段代碼,就知道了。若是重複註冊listener。其實就意味着一個packet會被notify屢次。for循環
程序就回出現一些奇怪的現象。class