我在Android的asmack库中遇到了一个奇怪的问题。该库使用ExecutorService来解析传入的数据包,如:
private ExecutorService listenerExecutor;
listenerExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
public Thread newThread(Runnable runnable) {
Thread thread = new Thread(runnable,
"Smack Listener Processor (" + connection.connectionCounterValue + ")");
thread.setDaemon(true);
return thread;
}
});
(...)
listenerExecutor.submit(new ListenerNotification(packet));
(...)
/**
* A runnable to notify all listeners of a packet.
*/
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);
}
}
}
一切正常,直到调用submit()方法,调用ListenerNotification的构造函数,但不再调用ListenerNotification中的run()方法。
这可能是什么原因? ExecutorService中是否有一些机制可能会导致调用提交被忽略?
答案 0 :(得分:0)
正如所预料的那样,错误就在我身边。
我在代码中实现了一个Roster Packet侦听器并覆盖了processPacket方法:
@Override
public void processPacket(Packet packet) {
if (packet instanceof RosterPacket) {
RosterPacket rosterPacket = (RosterPacket) packet;
Logger.d(LOGTAG, "Initial roster packet received: " + rosterPacket.getRosterItemCount());
mConnection.removePacketListener(this);
fireOnInitialRosterPacketReceived(rosterPacket);
}
}
但是,我的内部监听器调用方法引入了一个无限循环:
private void fireOnInitialRosterPacketReceived(RosterPacket rosterPacket) {
Iterator<SessionListener> it = mSessionListeners.iterator();
while (it.hasNext()) {
// it.next().onInitialRosterPacketReceived(mConnection,
// rosterPacket);
}
}
这阻止了执行程序启动的线程,以便后续的提交调用不会再次触发该线程。