2013-06-20 16 views
17

Come possiamo gestire le modifiche di orientamento, Activities/Fragments interrompendo/riprendendo utilizzando Volley?Volley Android - modifiche di orientamento

So che per GET richieste, la risposta verrà memorizzata nella cache e la seconda volta che tentiamo di fare tale richiesta, avremo una risposta in cache. (Se il server invia le intestazioni HTTP propri)

Ma cosa circa POST? Supponiamo che io faccia una richiesta POST (ad esempio, registro, che voglio succedere solo una volta), la mia app passa allo sfondo, la richiesta è finita mentre l'app è ancora in background, e poi torno all'app. Come ottengo il Response per quello Request o come mi ricollego ad esso, se è ancora in sospeso?

AFAIK non c'è praticamente alcun supporto per questo in Volley. Ho ragione? C'è un modo semplice per risolvere lo scenario sopra menzionato, usando Volley?

+5

"Come ottengo la risposta per quella richiesta, o come mi ricollego ad essa, se è ancora in sospeso?" - solo perché la tua app non è più in primo piano non impedisce l'esecuzione dei thread. Cosa ti fa pensare che la "Richiesta" non ti sia già stata consegnata? Utilizzare un frammento mantenuto per le operazioni asincrone, in modo che, indipendentemente dalle modifiche di orientamento, le operazioni asincrone abbiano una base stabile da comunicare. – CommonsWare

+0

per qualche motivo ho avuto l'impressione che 'Volley' non fornirà risposte se andiamo in background (come' Robospice'), ma hai ragione. Dobbiamo chiamare 'requestQueue.cancel (...)' per fermare la consegna. Sto ancora pensando a un modo semplice e semplice di trattare le nuove risposte in modo corretto durante "stop/ripresa". –

risposta

8

Volley non fornisce un meccanismo per questo fuori dalla scatola, ma si può guardare nella libreria Otto di Square per Android, è fatto per gestire situazioni come la vostra elegantemente.

Implementare l'ascoltatore per la richiesta Volley in modo che invii una risposta positiva sul Bus, racchiusa in un oggetto evento come "RegisterEventSuccess" (lo si definisce dall'utente). Lascia che le tue attività o frammenti si iscrivano a questo tipo di evento con il meccanismo @Subscribe di Otto. Se, ad esempio, un'attività lancia la richiesta Volley e muore a causa di una modifica dell'orientamento dello schermo, un'altra istanza dell'attività (anch'essa registrata sul bus Otto) può quindi ricevere l'evento che contiene la risposta della richiesta Volley.

Spero che questo sia stato utile.

+0

Questa soluzione sembra decisamente interessante. C'è un posto in cui hai implementato questo. Hai riscontrato problemi? – Rasmus

+1

Non riaprire una domanda morta ma stavo cercando alcuni esempi di Volley + Otto per la gestione di richieste/risposte, e questo ragazzo ha messo insieme un esempio abbastanza pulito di una fusione dei due https://github.com/tslamic/AndroidExamples/tree/master/HttpBinVolley – Selecsosi

+5

Utilizzando questa soluzione, come gestireste la possibilità che la risposta di rete ritorni nel momento in cui le attività stanno passando (tra onDestroy della prima attività e onCreate di quella appena orientata)? Qui, nessuna delle attività sarà registrata sul bus e in attesa dell'evento. I metodi di @Producer possono risolverlo, ma non sembrano adatti a funzionare come una cache di rete generica e non si allineano realmente con il modello originale. –

4

Ho ora tentato di rispondere alla preoccupazione di @ kyle-ivey in quanto le risposte che arrivano tra onPause() e onResume() sono state scartate. Questo è un problema reale in quanto l'ho sperimentato in un'applicazione live.

Il mio approccio si basa sul modello di bus eventi implementato nella risposta da Thomas Moerman, anche se ho reimpementato un'applicazione di esempio da zero. Dipende dallo Otto Event bus Library, dallo Gson e dallo Volley. È implementato in IntelliJ 13 Ultimate usando Maven tom per risolvere le dipendenze.

Soluzione: Aggiungo alle risposte precedenti una classe che funge da buffer di risposta HTTP che si assume la responsabilità di ascoltare gli eventi mentre l'attività sta passando. Al termine, l'attività esegue il polling attivo per tutte le risposte che potrebbero essere arrivate mentre l'attività è stata disconnessa al bus eventi. Si aggancia on/off nelle e onResume -Eventi accanto alla registrazione dell'evento-bus in un modo simile a questo:

@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 
} 

Ecco l'implementazione di the ResponseBuffer-class.

Caveat 1: Se l'attività non viene mai ripreso, e né stopAndProcess()stopAndPurge() è chiamato in qualsiasi attività futura, il tampone può essere una fonte di perdita di memoria. Sii consapevole di come lo usi. Un modello sicuro dovrebbe essere stopAndProcess() in onResume() in tutte le delle tue attività.

Caveat 2: non è thread-safe. Se deve venire un interruttore di contesto sulla linea che separa il punto in cui sta salvando le stelle e annulla la registrazione del bus degli eventi, potrebbe ricevere l'evento due volte o zero volte.

L'esempio include un po 'di codice di prova sotto forma di classi di interfaccia utente e di supporto, ma le classi principali si avrebbe bisogno, se si desidera utilizzare questo modello in progetti separati sono quelli nei seguenti pacchetti:

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

Vedere la github-repository OttoVolleyDoneRight per un esempio completo di interfaccia utente per il test.

+0

Mi piace molto questa strategia, grazie per la condivisione! –

0

C'è una soluzione semplice che ha risolto il mio problema con il download dei dati dalla rete utilizzando la libreria Volley. Se la tua app utilizza frammenti a causa delle raccomandazioni di Google, piuttosto che tutto ciò che dovresti fare per evitare il crash se l'utente ruota lo schermo mentre carica i dati viene messo setRetainInstance(true); nel metodo onCreateView del tuo frammento (-s).

@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; 
} 
Problemi correlati