2014-09-12 8 views
12

Ich kann einen Dienst nicht auflösen, während ein anderer gerade gelöst wird. Wenn das der Fehler ist ... Was ist der Weg zu warten, bis es gelöst ist?Listener wird bereits verwendet (Service Discovery)

@Override 
public void onServiceFound(NsdServiceInfo service) { 
    Log.d(TAG, "Service found. " + service); 
    if (service.getServiceType().equals(SERVICE_TYPE)) { 
     if (service.getServiceName().contains(mServiceName)) { 
      mNsdManager.resolveService(service, mResolveListener); 
     } 
    } 
} 

java.lang.IllegalArgumentException: Zuhörer bereits im Einsatz bei android.net.nsd.NsdManager.resolveService (NsdManager.java:613) bei com.example.miguel.broadcast.LocalService $ 2. onServiceFound (LocalService.java:145)

+0

Vielleicht hängt Ihr Problem mit diesem gemeldeten Fehler zusammen? https://code.google.com/p/android/issues/detail?id=56830 – Okas

+0

@Okas Ich benutze Android L und ich habe diesen Fehler nie erhalten. – Kenny

+0

Haben Sie jemals eine Lösung gefunden? Ich bekomme diesen Fehler auch auf meinem Lollipop-Gerät, aber nicht auf meinen anderen Geräten. –

Antwort

17

Sie müssen nicht warten! Wenn Sie sich die Javadocs für resolveService (NsdServiceInfo serviceInfo, NsdManager.ResolveListener listener) here Sie werden feststellen, dass für den Parameter Listener es sagt "Callback bei Erfolg oder Misserfolg erhalten. Kann nicht Null sein. Kann nicht für eine aktive Service-Lösung. "

daher dafür, um nur gehen Sie wie folgt zu arbeiten:

mNsdManager.resolveService(service, new MyResolveListener()); 

Wo MyResolveListener ist:

private class MyResolveListener implements NsdManager.ResolveListener { 
     @Override 
     public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { 
      //your code 
     } 

     @Override 
     public void onServiceResolved(NsdServiceInfo serviceInfo) { 
      //your code 
     } 
    } 

hoffe, das hilft :)

+0

Hey, danke für die Antwort. Ich kann mich nicht erinnern, wie ich das repariert habe, aber jetzt wäre es für das Internet nützlich! ;) – Kenny

+0

Es funktioniert nicht, wenn es zwei Geräte findet –

9

ich auch dieses Problem hatte, und hatte die Android NsdHelper-Implementierung verfolgt, die in NsdChat here ausgelegt wurde. In diesem Beispiel wird ein einzelner NsdManager.ResolveListener mResolveListener in der NsdHelper-Klasse erstellt und dieser ResolveListener für alle Aufrufe von NsdManager.resolveService verwendet.

Von here Ich lese, dass "ein separater Listener für jede aktive Registrierung oder Discovery-Anfrage verwendet werden soll".

Anstatt also eine Klassenvariable mResolveListener zu verwenden, erstellen Sie einen neuen Zuhörer jedes Mal, wenn mNsdManager.resolveService nennen:

@Override 
public void onServiceFound(NsdServiceInfo serviceInfo) { 
    Log.d(TAG, "Service found: "+ serviceInfo); 
    if (serviceInfo.getServiceType().equals(SERVICE_TYPE)){ 
     mNsdManager.resolveService(serviceInfo, new NsdManager.ResolveListener() { 
      @Override 
      public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { 
       Log.e(TAG, "Resolve Failed: " + serviceInfo); 
      } 
      @Override 
      public void onServiceResolved(NsdServiceInfo serviceInfo) { 
       Log.i(TAG, "Service Resolved: " + serviceInfo); 
      } 
     }); 
    } 
} 
3

Sie müssen sicherstellen, dass Sie nicht in einem Listener-Objekt unterwegs sind, die bereits registriert worden ist . Sie können das Commit sehen, das zu dieser Verhaltensänderung führte here. Hier

ist die Commit-Nachricht Text:

Dokument und durchzusetzen „eine Anforderung pro Listener“ -Regel

Die API und Implementierung von NsdManager implizieren, dass ein separater Listener verwendet werden soll für jede aktive Registrierung oder Entdeckung Anfrage. Dies ist nicht offiziell dokumentiert oder ordnungsgemäß durchgesetzt, und seltsame und unvorhersehbare Dinge passieren, wenn eine Anwendung einen Listener für mehr als eine Anfrage auf einmal verwendet.

Dokumentation aktualisieren, um dies explizit zu machen.

Erzwingen Sie die Einschränkung, wenn eine neue Anfrage für Verarbeitung eingereicht wird; Wenn der Listener bereits zum Verfolgen einer aktiven Anfrage verwendet wird, werfen Sie eine Ausnahme aus.

Dokument die Tatsache, dass Anwendungen sollten Dienste deregistrieren und Service Entdeckungen kündigen, wenn die App beendet wird (in KitKat und vor Mitteilungen, sie undicht werden, wenn dies nicht der Fall ist.)

Re-order " Lassen Sie den Listener "Vorgang, der vor dem Listener Callback stattfinden soll, damit der Listener von der Anwendung erneut verwendet werden kann, sobald der Rückruf eingegeben wurde - dies beseitigt eine Race Condition. Dokumentieren Sie dies.

Pass 2: Tippfehler, zusätzliche Dokumentation zu API-Ebene, geändert in Verwendung von ein explizit definierter Rückgabewert für "Busy Listener".

Auch nur eine Warnung, dass, wenn Sie das NsdChat Beispielprojekt aus der Android Developers-Website heruntergeladen (das heißt NsdChat.zip oder etwas in diese Richtung), dass der Projektcode wahrscheinlich nicht mehr aktuell ist.

Versuchen Sie stattdessen, den neuesten Code für den Master-Zweig zu verwenden. Sie können ihn kopieren und in Ihr Beispielprojekt von here einfügen.

+2

Leider ist die Master-Zweigprobe immer noch falsch gemacht ... – slott