2015-05-10 20 views
9

Sto usando volley per fare richieste HTTP dalla mia applicazione Android. Ecco il codice che sto utilizzando:Volley: richieste seriali anziché parallele?

public class RequestPool { 


    private static RequestPool mInstance; 

    private RequestQueue mRequestQueue; 

    private static Context mContext; 

    private RequestPool(Context context) { 

     mContext = context; 
     mRequestQueue = getRequestQueue(); 


    } 

    public static synchronized RequestPool getInstance(Context context) { 

     if (mInstance == null) { 
      mInstance = new RequestPool(context); 
     } 
     return mInstance; 
    } 

    public RequestQueue getRequestQueue() { 
     if (mRequestQueue == null) { 
      // getApplicationContext() is key, it keeps you from leaking the 
      // Activity or BroadcastReceiver if someone passes one in. 
      mRequestQueue = Volley.newRequestQueue(mContext.getApplicationContext()); 
     } 

     return mRequestQueue; 
    } 

    public <T> void addToRequestQueue(Request<T> req) { 

     getRequestQueue().add(req); 
    } 
} 

voglio aggiungere le richieste alla coda, ma controllare il modo in cui vengono eseguite, ad esempio:

l'aggiunta di richieste multiple per la piscina a volte arbitrari, il pool eseguirà solo la prima richiesta (capo della coda), quindi quando termina verrà eseguito il successivo ... e così via ....

Forse c'è un modo per rendere entrambe le richieste seriali e parallele esecuzione?

È possibile?

Grazie.

risposta

17

questo può essere fatto con la creazione di una richiesta con il pool di thread come 1.

int MAX_SERIAL_THREAD_POOL_SIZE = 1; 
final int MAX_CACHE_SIZE = 2 * 1024 * 1024; //2 MB 

private static RequestQueue prepareSerialRequestQueue(Context context) { 
    Cache cache = new DiskBasedCache(context.getCacheDir(), MAX_CACHE_SIZE); 
    Network network = getNetwork(); 
    return new RequestQueue(cache, network, MAX_SERIAL_THREAD_POOL_SIZE); 
} 

a getNetwork metodo()

private static Network getNetwork() { 
    HttpStack stack; 
    if(Build.VERSION.SDK_INT >= 9) { 
     stack = new HurlStack(); 
    } else { 
     String userAgent = "volley/0"; 
     stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent)); 
    } 
    return new BasicNetwork(stack); 
} 

e noi il metodo start per avviare() la coda di richieste .

RequestQueue serialRequestQueue = prepareSerialRequestQueue(context); 
serialRequestQueue.start(); 

Ora aggiungere la richiesta a questa coda in attesa della coda di richiesta delle chiamate dirette. Ad esempio:

StringRequest requestOne = new StringRequest(Request.Method.GET, "http://www.example1.com", this, this); 
StringRequest requestTwo = new StringRequest(Request.Method.GET, "http://www.example2.com", this, this); 
StringRequest requestThree = new StringRequest(Request.Method.GET, "http://www.example3.com", this, this); 
serialRequestQueue.add(requestTwo); 
serialRequestQueue.add(requestOne); 
serialRequestQueue.add(requestThree); 

in questo caso il risultato requestTwo saranno trattati prima seguita rispettivamente da requestOne e requestThree. Questo aiuta se non vuoi bloccare l'elaborazione della richiesta, e anche farla accadere in serie.

+0

È possibile ottenere il risultato [qui] (https: // gist.github.com/zaidhoona/af33539d3b8ede09353b) –

+0

puoi aiutarmi? la mia domanda è come posso gestire la risposta tutte e 3 le richieste – MilapTank

+0

Ci sono dei parametri in una funzione quando si crea una richiesta, è possibile fornire il parametro lì. È il parametro 'Response.Listener' che ti aiuterà a farlo. Puoi vedere [qui] (http://developer.android.com/training/volley/requestqueue.html#network), vedere come viene creato 'StringRequest' per ottenere la risposta. –

3

Se si desidera eseguire richieste parallele, è sufficiente continuare ad aggiungere richieste alla coda. Le richieste sono di default asincrone.

Se si desidera eseguire richieste seriali, esistono due approcci.

Uno consiste nell'aggiungere la seconda richiesta all'interno della prima richiesta onResponse. Questo fondamentalmente concatena più richieste asincrone.

Due è utilizzare RequestFuture che sta bloccando. Ad esempio, l'esecuzione di questo metodo bloccherà fino a quando non si ottiene una risposta.

private String blockingRequest(String url) { 

    RequestFuture<String> future = RequestFuture.newFuture(); 

    StringRequest sr = new StringRequest(url, future, future); 
    queue.add(sr); 
    String response = null; 

    try { 
     response = future.get(); 
    } catch (InterruptedException | ExecutionException e) { 
     e.printStackTrace(); 
    } 
    return response; 
} 

Per utilizzare fondamentalmente impilare più metodi di richiesta di blocco in questo modo:

String response1 = blockingRequest1(url1); 
// other methods 
String response2 = blockingRequest2(url2); 

blockingRequest2 viene eseguito dopo che blockingRequest1 ha completato. Senza futuro entrambi i metodi saranno eseguiti simultaneamente. Inutile dire che sarà necessario eseguire i metodi di blocco non nel thread dell'interfaccia utente (ad esempio Thread, AsyncTask e RxJava Observable preferito personale).

+0

Grazie per la rapida risposta. In realtà sto già usando il primo approccio.Il problema è che ci sono più thread che aggiungono una richiesta al pool di richieste. Quindi potrei usare entrambi i metodi che hai citato. Qualche possibilità di ottenere l'uso di "blockingRequest"? – sharonooo

+0

Non c'è molta storia ma ho modificato la mia risposta per illustrarla. RequestQueue come suggerisce il nome, solo le richieste di code nell'ordine FIFO (first in first served). È già sincronizzato, quindi non devi preoccuparti di accedervi da più thread. – inmyth

+0

Sono paralleli, ma farò notare che il numero di richieste in esecuzione simultanea è controllato da una dimensione del pool di thread che è per impostazione predefinita 4 (DEFAULT_NETWORK_THREAD_POOL_SIZE in RequestQueue) – user3175580

Problemi correlati