2013-06-20 22 views
17

Wie können wir mit Orientierungsänderungen umgehen, Activities/Fragments Stoppen/Fortsetzen mit Volley?Android Volley - Orientierungsänderungen

Ich weiß, dass für GET Anfragen, wird die Antwort im Cache gespeichert werden und das zweite Mal, wir versuchen, diesen Antrag zu machen, werden wir eine zwischengespeicherte Antwort erhalten.

(wenn der Server den richtigen HTTP-Header sendet) Aber was über POST? Angenommen, ich mache eine POST Anfragen (d. H. Registrieren, die ich nur einmal passieren möchte), meine App geht in den Hintergrund, Anfrage ist abgeschlossen, während App noch im Hintergrund ist, und dann gehe ich zurück zur App. Wie bekomme ich die Response für diese Request, oder wie kann ich wieder verbinden, wenn es noch aussteht?

AFAIK gibt es so ziemlich keine Unterstützung in Volley. Habe ich recht? Gibt es eine einfache Möglichkeit, das oben genannte Szenario mit Volley zu lösen?

+5

"Wie bekomme ich die Antwort für diese Anfrage, oder wie stelle ich eine Verbindung zu ihr her, wenn sie noch aussteht?" - Nur weil Ihre App nicht mehr im Vordergrund ist, können Threads nicht ausgeführt werden. Was lässt Sie denken, dass die "Anfrage" Ihnen noch nicht zugestellt wurde? Verwenden Sie ein beibehaltenes Fragment für asynchrone Operationen, so dass Ihre asynchronen Operationen unabhängig von den Orientierungsänderungen eine stabile Basis für die Kommunikation haben. – CommonsWare

+0

Aus irgendeinem Grund hatte ich den Eindruck, dass 'Volley' keine Antworten liefert, wenn wir in den Hintergrund gehen (wie' Robospice'), aber Sie haben Recht. Wir müssen 'requestQueue.cancel (...)' aufrufen, um die Zustellung zu stoppen. Ich denke immer noch an eine nette, einfache Art und Weise, wie ich Antworten während "stop/resume" richtig wiedergeben kann. –

Antwort

8

Volley bietet keinen Mechanismus für diese out of the Box, aber Sie können in Quads Otto Bibliothek für Android suchen, es ist gemacht, um Situationen wie Ihre elegant zu behandeln.

Implementieren Sie den Listener für die Volley-Anforderung so, dass er eine erfolgreiche Antwort auf den Bus schreibt, verpackt in einem Ereignisobjekt wie "RegisterEventSuccess" (Sie definieren dies selbst). Lassen Sie Ihre Aktivitäten oder Fragmente diesen Ereignistyp mit Ottos @ Subscribe-Mechanismus abonnieren. Wenn beispielsweise eine Aktivität die Volley-Anforderung startet und aufgrund einer Änderung der Bildschirmausrichtung abstirbt, kann eine andere (ebenfalls auf dem Otto-Bus registrierte) Activity-Instanz das Ereignis empfangen, das die Antwort der Volley-Anforderung enthält.

Ich hoffe, das war nützlich.

+0

Diese Lösung klingt definitiv interessant. Gibt es einen Ort, an dem du das implementiert hast? Sind Sie auf irgendwelche Probleme gestoßen? – Rasmus

+1

Nicht eine tote Frage wieder zu öffnen, aber ich suchte nach einigen Beispielen von Volley + Otto für Anfrage/Antwort-Management, und dieser Typ zusammen ein ziemlich sauberes Beispiel für eine Verschmelzung der beiden https://github.com/tslamic/AndroidExamples/tree/master/HttpBinVolley – Selecsosi

+5

Wie würden Sie bei dieser Lösung mit der Möglichkeit umgehen, dass die Netzwerkantwort in dem Moment zurückkehrt, in dem die Aktivitäten übergehen (zwischen onDestroy der ersten Aktivität und onCreate der neu ausgerichteten)? Hier wird keine der Aktivitäten im Bus registriert und wartet auf die Veranstaltung. Die @Producer-Methoden können dies zwar beheben, aber sie scheinen nicht wirklich geeignet zu sein, als generischer Netzwerk-Cache zu funktionieren und passen nicht wirklich zum ursprünglichen Muster. –

4

Ich habe jetzt versucht, das Anliegen von @ kyle-ivey dahingehend zu adressieren, dass Antworten zwischen onPause() und onResume() verworfen werden. Dies ist ein echtes Problem, wie ich es in einer Live-Anwendung erlebt habe.

Mein Ansatz baut auf dem Ereignisbusmuster auf, das in der Antwort von Thomas Moerman implementiert wurde, obwohl ich eine Beispielanwendung von Grund auf neuimplementiert habe. Es hängt von der Otto Event bus Library, Gson und Volley. Es wird in IntelliJ 13 Ultimate mit Maven Tom implementiert, um die Abhängigkeiten aufzulösen.

Lösung: Ich füge zu den vorherigen Antworten eine Klasse hinzu, die als ein HTTP-Antwortpuffer fungiert, der die Verantwortung übernimmt, Ereignisse zuzuhören, während die Aktivität übergeht. Wenn dies erledigt ist, fragt die Aktivität aktiv nach Antworten, die möglicherweise eingetroffen sind, während die Aktivität auf den Ereignisbus getrennt wurde. Es hakt an/aus in den und onResume -Veranstaltungen neben dem Ereignis-Bus Registrierung in einer Art und Weise wie folgt aus:

@Override 
protected void onPause() { 
    super.onPause(); 
    ServiceLocator.ResponseBuffer.startSaving(); // The buffer takes over 
    ServiceLocator.EventBus.unregister(this); // Unregistering with Otto 
} 

@Override 
protected void onResume() { 
    ServiceLocator.EventBus.register(this);   // Re-registering 
    ServiceLocator.ResponseBuffer.stopAndProcess(); // Process any responses buffered 
} 

Hier ist die Implementierung von the ResponseBuffer-class.

Caveat 1: Wenn die Aktivität nicht wieder aufgenommen wird, und weder stopAndProcess() noch stopAndPurge() wird in einer zukünftigen Tätigkeit der Puffer kann eine Quelle des Speicherverlustes genannt. Sei dir bewusst, wie du es benutzt. Ein sicheres Muster wäre stopAndProcess() in onResume() in alle Ihrer Aktivitäten zu haben.

Vorbehalt 2: Es ist nicht Thread-sicher. Wenn ein Kontextwechsel zwischen der Zeile, in der das Speichern gespeichert wird, und der Registrierung des Ereignisbusses stattfindet, kann das Ereignis zweimal oder null Mal empfangen werden.

Das Beispiel enthält einige Testcode in Form von UI und Support-Klassen, aber die wichtigsten Klassen würden Sie brauchen, wenn Sie dieses Muster in einem separaten Projekten nutzen wollen, sind diejenigen, die in den folgenden Paketen:

  • nilzor.ottovolley.core
  • nilzor.ottovolley.messages

Siehe github-Repository OttoVolleyDoneRight für ein komplettes Beispiel mit UI zum Testen.

+0

Ich mag diese Strategie wirklich, danke fürs Teilen! –

0

Es gibt eine einfache Lösung, die mein Problem beim Herunterladen von Daten aus dem Netzwerk mithilfe der Volley-Bibliothek gelöst hat. Wenn Ihre App aufgrund der Empfehlungen von Google Fragmente verwendet, sollten Sie alles, was Sie tun sollten, um einen Absturz zu verhindern, wenn der Benutzer beim Laden der Daten den Bildschirm dreht, in die Methode setRetainInstance(true); Ihres Fragments (-s) eingeben.

@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View theView = inflater.inflate(R.layout.fragment_studios, container, false); 
    setRetainInstance(true); 
    lvStudios = (ListView) theView.findViewById(R.id.lvStudios); 
    return theView; 
}