2016-01-29 8 views
15

Ich habe einen Retrofit Netzanruf, dass id alle 5 Sekunden laufen mag. Mein aktueller Code:Retrofit „Illegal: Bereits ausgeführt“

Handler h = new Handler(); 
int delay = 5000; //milliseconds 

h.postDelayed(new Runnable() { 
    public void run() { 
     call.enqueue(new Callback<ApiResponse>() { 
      @Override 
      public void onResponse(Response<ApiResponse> response) { 
       Log.d("api", "response: " + response.body().getPosition().getLatitude().toString()); 
      } 

      @Override 
      public void onFailure(Throwable t) { 

      } 
     }); 
     h.postDelayed(this, delay); 
    } 
}, delay); 

Dies läuft einmal, aber dann wirft die folgende:

java.lang.IllegalStateException: Bereits ausgeführt. bei retrofit2.OkHttpCall.enqueue (OkHttpCall.java:52) bei retrofit2.ExecutorCallAdapterFactory $ ExecutorCallbackCall.enqueue (ExecutorCallAdapterFactory.java:57) bei orbyt.project.MyFragment $ 1.run (MyFragment.java:93)

Was ist das Problem hier?

Als Bonus: Was ist ein besserer Weg, damit umzugehen? Ich werde bei jedem Update eine Karte aktualisieren. Ich habe über den Versuch nachgedacht, Rx zu verwenden, bin mir aber nicht sicher, ob dies ein geeigneter Anwendungsfall ist oder wie man es implementiert.

+0

ist es möglich, dass Ihr Netzwerkanruf länger als 5 Sekunden dauert, wenn also die zweite Iteration beginnt, ist die erste Iteration noch nicht beendet? Die Verzögerung startet nicht, wenn die erste Iteration beendet, aber 5 Sekunden aus der Zeit genannt, um das ersten Iteration – TooManyEduardos

+0

@TooManyEduardos gut weiß, dass ich für eine Tatsache, der erste Anruf abgeschlossen wird, weil Im die Antwort anmelden, und bin in der Tat immer Daten. – Orbit

+0

aber das Protokoll zeigt Ihnen nur die empfangenen Daten, nicht die Netzwerkverbindung beendet. Es könnte immer noch schließen Elemente innerhalb der 5 Sekunden Fenster. Dies ist nur eine Idee, aber versuchen Sie, die Verzögerung auf 15 Sekunden zu erhöhen und sehen Sie, ob das Problem verschwindet – TooManyEduardos

Antwort

45

Ein Call kann nur einmal verwendet werden. Its documentation erfahren Sie, wie man sie mehrmals verwenden:

Verwenden clone() mehrere Anrufe mit den gleichen Parametern auf den gleichen Webserver zu machen; Dies kann verwendet werden, um das Abrufen zu implementieren oder einen fehlgeschlagenen Anruf erneut zu versuchen.

So call.clone().enqueue(..) verwenden, um sicherzustellen, dass Sie eine frische, nicht ausgeführte Call für jede Anforderung.

+0

Super, danke. – Orbit