2016-02-19 22 views
6

Więc mam prośbę Volley PUT:Android wolej DefaultRetryPolicy nie działają zgodnie z przeznaczeniem

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]; 
} 

Moim problemem jest to, że mogę wysłać bardzo duży JSON, więc domyślny limit czasu 5 sekund nie wystarczy. Tak więc, próbowałem zwiększyć limit czasu do 30 sekund i mieszać się z DefaultRetryPolicy, aby zwiększyć liczbę ponownych prób.

Chodzi o to, że zachowuje timeouting w 5 sekund i nawet nie próbuje ponownie!

Czy muszę mieć detektora lub wywołania zwrotnego dla ponownych prób? Robię coś nie tak z DefaultRetryPolicy? Proszę pomóc, ten problem doprowadza mnie do szału ...

Odpowiedz

4

Czy potrzebujesz użyć DefaultRetryPolicy?

Ponieważ można zdefiniować własne.

Zamiast tego:

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

Spróbuj tego:

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

Tworzę własne zasady. Żądanie nie kończy się (timeout 10, spróbuj 3). Używam żądania łańcucha. –

+1

@ user2362956 Otwórz nowe pytanie z kodem i wyjaśnij swoje próby i wyniki. – herrmartell

1

nie jestem pewien dokładnie, dlaczego czas ponawiania nie działa na kodzie, znalazłem podobny problem here chociaż.

Zamiast tego, mogę powiedzieć wam kilka rzeczy, które nie są w porządku w waszym kodzie i sugerują, aby przyjąć mój model użycia Volley.

Przede wszystkim tworzysz nową kolejkę żądań dla każdego tworzonego żądania. To nie jest fajne, powinieneś mieć singleton RequestManager, który ma jedną kolejkę żądań i używać jej.

Po drugie, nie wiem, czy to wpływa na czas ponawiania, mam klasę żądania podstawowego i ustawię czas ponawiania w konstruktorze. Następnie rozszerzam tę klasę za każdym razem, gdy muszę wprowadzić nowy typ żądania. Następnie tworzę instancję żądania, ustawiam wywołania zwrotne i przekazuję je do menedżera żądań. Menedżer żądań dodaje go do kolejki jednego żądania, o której mówiłem.

Ponadto, jeśli jeszcze tego nie zrobiłeś, sugeruję użycie biblioteki Gson do analizy obiektów JSON.

To moja prośba klasa bazowa Używam:

/** 
* 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` 

To działa jak urok dla mnie. Mam nadzieję, że pomoże, jeśli potrzebujesz dalszej pomocy, skontaktuj się ze mną