2013-11-15 17 views
9

Sto cercando di inviare un'immagine con i miei dati di post al mio assistente da Android. Per realizzare questa base ho 64 codificato la mia immagine a stringa e lo ha inviato utilizzando la libreria volley Android. Questo sta causando problemi però. Per qualche ragione a volte invia il post due volte, e non riesco a capire perché. Di seguito è riportata la funzione che viene chiamata per inviare la richiesta di post. Ho messo un segno di pausa al String url = "http://domain.com/ajax_ws.php"; e poi uno alla protected Map<String, String> getParams() { Quello che ho trovato è l'String url = ... è solo essere chiamata una volta ma quando si invia due, il protected Map... viene chiamato due volte. Non riesco a trovare alcuna documentazione su Android volley, quindi non so perché questo sta accadendo. La bitmap viene ridimensionata in modo che la stringa di immagine sia costantemente compresa tra 100 e 200 caratteri. Ho pensato che forse era un problema di dimensioni ma il mio server sta ricevendo le immagini e decodificandole e tutto va bene.Android volley sta inviando le informazioni due volte con il caricamento di immagini

public void Sharing() { 

    pd = ProgressDialog.show(getParent(), null, "Please Wait..."); 
    final String caption = mEtMessage.getText().toString(); 
    RequestQueue queue = Volley.newRequestQueue(this); 
    String url = "http://domain.com/ajax_ws.php"; 
    StringRequest postRequest = new StringRequest(
      Request.Method.POST, 
      url, 
      new MyStringListener(), 
      new MyErrorListener() 
    ) { 
     @Override 
     protected Map<String, String> getParams() { 
      Map<String, String> params = new HashMap<String, String>(); 
      params.put("token", "secretToken"); 
      params.put("mode", "createVoucher"); 
      params.put("user_id", ActivityLogin.id); 
      params.put("deal_id", ActivitySharing.id_deal); 
      params.put("user_id_company", ActivityRestaurantDetails.res.getId()); 
      params.put("user_img", pathImage); 
      params.put("caption", caption); 
      params.put("company_id", ActivityRestaurantDetails.res.getId()); 
      return params; 

     } 
    }; 
    queue.add(postRequest); 
} 

Qualsiasi idea del perché questo potrebbe accadere?

+0

Solo un suggerimento: Sarebbe bene estrarre anonimo 'Response.Listener' per separare (inner?) Classe per semplificare le cose e rendere il codice più leggibile. Al momento è abbastanza ingombrante e rende la metà dello schermo coperta da trattini. –

+0

@Secator Grazie, lo farò, questo codice è stato attraverso lo strizzatore, è tutto finito. – tomjung

+0

Sto affrontando il problema esatto. La mia ulteriore indagine mostra che si tratta di una connessione lenta. Ho provato a eseguire il debug della libreria Volley e ho trovato uno schema che il doppio post è causato dalla SocketTimeoutException nella classe BasicNetwork nel metodo "performRequest (richiesta richiesta)". Ogni volta che viene sollevata l'eccezione, avviene un doppio post. Sfortunatamente non ho alcuna soluzione per questo. Fammi sapere il tuo pensiero. E inoltre, non vedo questo correlato a RetryPolicy. Qualsiasi numero inserito in RetryPolicy non influirà sulla correzione. –

risposta

4

Volley utilizza un RetryPolicy per le richieste di elaborazione che per default invia la richiesta fino a 3 volte con un algoritmo di backoff esponenziale. È possibile che alcune richieste falliscano e vengano riprovate? Ricevi eventuali errori/log di successo per la prima chiamata della richiesta?

+0

Hai ragione. Ho fatto qualche altro test, e succede con l'immagine più grande. Questo crea un altro problema, e questo è come gestire questo problema. Ho alcune idee ma non ho esperienza in quest'area quindi ho postato un'altra domanda [qui] (http://stackoverflow.com/questions/20011775/sending-image-via-android-volley-with-php) Grazie per la tua risposta! – tomjung

+0

Per comprendere la politica di riprova, si prega di fare riferimento a questo [Retry Policy] (https://github.com/smanikandan14/Volley-demo) '.'Retry Policy' contiene 3 parametri' RequestTimeOut, Retries, Multiplier' .RequestTimeOut' è il tempo in cui la libreria 'Volley' attende la risposta' Http'. Durante quel tempo se non arriva nessuna risposta, fa la stessa 'richiesta Http'. Il numero di tentativi è fatto come per il valore di 'Retries'. Se 'Retry Policy = 1', e quando 'Request TimeOut' viene superato, effettua la stessa' richiesta Http' solo una volta. – laaptu

7

io sono in grado di risolvere questo problema in due modi.

Il primo è suggerito da Snicolas. Modificato il RetryPolicy. sufficiente impostare il valore di timeout di raddoppiare il timeout predefinito. Ha funzionato bene Puoi anche provare altri valori.

request.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 2, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); 

altro modo è modificando connection.setChunkedStreamingMode(0); in openConnection metodo HurlStack classe.

sto creando il mio RequestQueue come questo requestQueue = Volley.newRequestQueue(context, new HurlStack());

Speranza che aiuta :)

3

La correzione di seguito ha lavorato per me. Coloro che lavorano con HTTPS e volley dovrebbero provare questo.

DefaultRetryPolicy retryPolicy = new DefaultRetryPolicy(0, -1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT); 
     jsr.setRetryPolicy(retryPolicy); 

Spero che questo ti aiuti a risolvere il problema.

6

La risoluzione è modificare il criterio di riprova che viene anche spiegato qui: (http://www.techstricks.com/avoid-multiple-requests-when-using-volley/).

Tuttavia, se l'override non funziona per te allora, potresti voler rivisitare la tua logica del "volley caching". A causa del soft ttl nella cache di volley, il risultato viene consegnato dalla cache e allo stesso tempo accoda un'altra richiesta di rete che restituirà anche un risultato. E quindi, una singola richiesta ma due risultati diversi.

1

Prova questo.

JsonObjectRequest jsonObjRequest = new JsonObjectRequest(...); 
jsonObjRequest.setRetryPolicy(new DefaultRetryPolicy(0, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); 
1

modificare il numero di tentativi in ​​1. ha funzionato per me.

stringRequest.setRetryPolicy(new 
      DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 2, 1, 
          DefaultRetryPolicy.DEFAULT_BACKOFF_MULT) 
       ); 
Problemi correlati