2013-04-06 3 views
0

Я столкнулся с странной проблемой в библиотеке asmack для Android. Библиотека использует ExecutorService для анализа входящих пакетов, например, что:ExecutorService не вызывает run() в Runnable

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); 
     } 
    } 
} 

Это все работает отлично до точки, когда представить() вызывается метод, конструктор ListenerNotification также называется, но метод запуска() в ListenerNotification больше не называется.

В чем причина этого? Существуют ли какие-либо механизмы в ExecutorService, которые могут вызвать призыв к отправке для игнорирования?

+0

Выполняется ли 'ListenerNotification.run()' один раз? Вы пытались использовать по умолчанию ThreadFactory, а не свой собственный? –

+0

Да, это работает некоторое время, а затем останавливается. Это не является детерминированным или воспроизводимым, что заставляет меня задуматься ... Я не внес изменений в этот код библиотеки - я использую его только в двух моих проектах. Раньше я использовал одну и ту же библиотеку, и у меня не было проблем такого характера, и теперь они появились. Я даже удалил свой собственный слушатель из списка слушателей, который повторяется в методе run(), потому что я думал, что, может быть, все, что я делаю, занимает слишком много времени, но это тоже не помогло. – PawelPredki

+0

Попробуйте более старую версию lib и посмотрите, действительно ли она там происходит. Возможно, один исполнитель потока находится в некотором «заблокированном» состоянии. Это первый отчет такого поведения aSmack, о котором я слышал. – Flow

ответ

0

Как и следовало ожидать, вина была на моей стороне.

Я реализовал слушатель Учетных пакетов в моем коде и отменяю метод 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); 
    } 
} 

Это заблокированное нить началась исполнителем, чтобы последующие вызовы представить не возобновляли поток снова.