2016-02-19 17 views
6

Così, ho questa richiesta Volley PUT:Android volley DefaultRetryPolicy non funzionare come previsto

private boolean syncCall(JSONObject jsonObject, final VolleyCallback 
     callback) { 

    final ProgressDialog progDailog = new ProgressDialog(context); 

    final Boolean[] success = {false}; 

    progDailog.setMessage("..."); 
    progDailog.setIndeterminate(false); 
    progDailog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 

    progDailog.setCancelable(false); 
    progDailog.show(); 

    final SharedPreferences prefs = PreferenceManager 
      .getDefaultSharedPreferences(context); 

    RequestQueue queue = Volley.newRequestQueue(context, new HurlStack()); 

    final String token = prefs.getString("token", null); 

    String URL = Constants.getUrlSync(); 
    String param1 = String.valueOf(prefs.getInt("pmp", 1)); 
    String param2 = String.valueOf(prefs.getInt("ei", 1)); 

    URL = URL.replace("[x]", param1); 
    URL = URL.replace("[y]", param2); 

    //pegar id pmp e IE corretas 
    JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request 
      .Method.PUT, URL, jsonObject, 
      new Response.Listener<JSONObject>() { 
       @Override 
       public void onResponse(JSONObject response) { 
        callback.onSuccess(response + ""); 
        success[0] = true; 
        progDailog.dismiss(); 
       } 
      }, 
      new Response.ErrorListener() { 
       @Override 
       public void onErrorResponse(VolleyError error) { 

        callback.onFailure(error); 
        tokenFailure(error); 
        success[0] = false; 
        progDailog.dismiss(); 
       } 
      }) { 


     @Override 
     public Map<String, String> getHeaders() throws 
       AuthFailureError { 

      HashMap<String, String> headers = new HashMap<>(); 
      headers.put("Token", token); 

      return headers; 
     } 
    }; 

    int socketTimeout = 30000; 
    RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT); 

    jsObjRequest.setRetryPolicy(policy); 


    queue.add(jsObjRequest); 

    return success[0]; 
} 

mio problema è che io mando un grande JSON, in modo che il timeout predefinito di 5 secondi non è sufficiente. Così, ho provato ad aumentare il timeout a 30 secondi e a scherzare con lo DefaultRetryPolicy per aumentare il numero di tentativi.

Il fatto è che mantiene timeouting in 5 secondi e non riprovare nemmeno una volta!

Devo avere un listener o un callback per i tentativi? Sto facendo qualcosa di sbagliato con lo DefaultRetryPolicy? Per favore aiutatemi, questo problema mi sta facendo impazzire ...

risposta

4

Avete bisogno di usare DefaultRetryPolicy?

Perché è possibile definire il proprio.

Invece di questo:

RetryPolicy policy = new DefaultRetryPolicy(socketTimeout,  
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,  
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT); 

Prova questo:

jsObjRequest.setRetryPolicy(new RetryPolicy() { 
    @Override 
     public int getCurrentTimeout() { 
      // Here goes the new timeout 
      return mySeconds; 
     } 
     @Override 
     public int getCurrentRetryCount() { 
      // The max number of attempts 
      return myAttempts; 
     } 
     @Override 
     public void retry(VolleyError error) throws VolleyError { 
      // Here you could check if the retry count has gotten 
      // To the max number, and if so, send a VolleyError msg 
      // or something  
     } 
    }); 
+0

Ho creato la mia politica. La richiesta non termina (timeout 10, riprova 3). Io uso la richiesta di stringhe. –

+1

@ user2362956 Apri una nuova domanda con il tuo codice e spiegando i tuoi tentativi e risultati, per favore. – herrmartell

1

io non so esattamente il motivo per cui il numero di tentativi non funziona sul vostro codice, ho trovato un problema simile here anche se.

Invece, posso dirvi alcune cose che non credo possano essere accettabili nel vostro codice e suggerirvi di adottare il mio modello di utilizzo di Volley.

Prima di tutto, stai creando una nuova coda di richieste per ogni richiesta che stai facendo. Non è bello, dovresti avere un singleton RequestManager che contiene una coda di richieste e usarla.

In secondo luogo, non so se questo è ciò che influenza il tempo di retry, ho una classe di richiesta di base e impostare il tempo di retry nel costruttore. Quindi, estendo questa classe ogni volta che devo implementare un nuovo tipo di richiesta. Quindi, creo un'istanza della richiesta, imposta i callback e la trasmetto al gestore richieste. Il manager della richiesta lo aggiunge alla coda di una sola richiesta di cui stavo parlando.

Inoltre, se non lo si è già, suggerisco di utilizzare la libreria Gson per analizzare gli oggetti JSON.

Questa è la mia classe di richiesta di base sto usando:

/** 
* Created by Daniel on 2/6/2016. 
*/ 
public class GsonRequest<T> extends Request<T> { 

protected Context context; 
protected final Gson gson = new Gson(); 
protected final Class<T> clazz; 
protected final TypeToken typeToken; 
protected Map<String, String> headers; 
protected Map<String, String> params; 
protected final Response.Listener<T> listener; 

/** 
* Make a GET request and return a parsed object from JSON. 
* 
* @param url URL of the request to make 
* @param clazz Relevant class object, for Gson's reflection 
*/ 
public GsonRequest(final Context context, final int requestMethod, String url, Class<T> clazz, Response.Listener<T> listener, Response.ErrorListener errorListener) { 
    super(requestMethod, url, errorListener); 
    this.context = context; 
    this.clazz = clazz; 
    this.listener = listener; 
    this.headers = new HashMap<>(); 
    typeToken = null; 
    setRetryPolicy(); 
} 

/** 
* Make a GET request and return a parsed object from JSON. 
* 
* @param url  URL of the request to make 
* @param typeToken Relevant typeToken object, for Gson's reflection 
*/ 
public GsonRequest(final Context context, final int requestMethod, String url, TypeToken typeToken, Response.Listener<T> listener, Response.ErrorListener errorListener) { 
    super(requestMethod, url, errorListener); 
    this.context = context; 
    this.typeToken = typeToken; 
    this.listener = listener; 
    this.headers = new HashMap<>(); 
    clazz = null; 
    setRetryPolicy(); 
} 

@Override 
protected Map<String, String> getParams() throws AuthFailureError { 
    return params != null ? params : super.getParams(); 
} 

@Override 
public Map<String, String> getHeaders() throws AuthFailureError { 
    //TODO add headers here 
    return headers; 
} 

@Override 
protected void deliverResponse(T response) { 
    listener.onResponse(response); 
} 

@Override 
protected Response<T> parseNetworkResponse(NetworkResponse response) { 
    try { 
     String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); 
     JSONObject jsonObject = new JSONObject(json); 
     if (clazz != null) { 
      return Response.success(gson.fromJson(json, clazz), HttpHeaderParser.parseCacheHeaders(response)); 
     } else { 
      return Response.success((T) gson.fromJson(json, typeToken.getType()), HttpHeaderParser.parseCacheHeaders(response)); 
     } 
    } catch (UnsupportedEncodingException e) { 
     return Response.error(new ParseError(e)); 
    } catch (JsonSyntaxException e) { 
     return Response.error(new ParseError(e)); 
    } catch (JSONException e) { 
     return Response.error(new ParseError(e)); 
    } 
} 

protected void setRetryPolicy() { 
    //TODO set your retry policy here 
    setRetryPolicy(new DefaultRetryPolicy(
      30000, 
      DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
      DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); 
} 
}`enter code here` 

Questo funziona come un fascino per me. Spero che ti aiuti, se hai bisogno di ulteriore aiuto, contattami