2016-02-19 3 views
6

Итак, у меня есть этот запрос Volley PUT:Android залп DefaultRetryPolicy не работают по назначению

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

Моя проблема в том, что я посылаю очень большой JSON, поэтому таймаут по умолчанию 5 секунд не хватает. Итак, я попытался увеличить тайм-аут до 30 секунд и возиться с DefaultRetryPolicy, чтобы увеличить количество попыток.

Дело в том, что он держит timeouting в 5 секунд, и он даже не повторяет попытку!

Должен ли я иметь слушателя или обратный вызов для повторных попыток? Я делаю что-то не так с DefaultRetryPolicy? Пожалуйста, помогите, эта проблема сводит меня с ума ...

ответ

4

Вам нужно использовать DefaultRetryPolicy?

Потому что вы можете определить свои собственные.

Вместо этого:

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

Попробуйте это:

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

Я создаю свою собственную политику. Запрос не завершается (тайм-аут 10, повторите попытку 3). Я использую запрос строки. –

+1

@ user2362956 Задайте новый вопрос своим кодом и объясните свои попытки и результаты. – herrmartell

1

Я точно не знаю, почему время повтора не работает на вашем коде, я нашел подобный вопрос here хоть.

Вместо этого я могу рассказать вам некоторые вещи, которые, как я считаю, не соответствуют вашим кодам и предлагают принять мою модель использования волейбола.

Прежде всего, вы создаете новую очередь запросов для каждого запроса, который вы делаете. Это не здорово, у вас должен быть singleton RequestManager, который содержит одну очередь запросов и использует ее.

Во-вторых, я не знаю, влияет ли это на время повтора, у меня есть класс базового запроса и задано время повторения в конструкторе. Затем я расширяю этот класс всякий раз, когда мне нужно реализовать новый тип запроса. Затем я создаю экземпляр запроса, устанавливаю обратные вызовы и передаю его в диспетчер запросов. Менеджер запросов добавляет его в одну очередь запросов, о которой я говорил.

Более того, если вы этого еще не сделали, я предлагаю вам использовать библиотеку Gson для анализа объектов JSON.

Это мой базовый класс запрос я использую:

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

Это работает как шарм для меня. Надеюсь, что это поможет, если вам нужна дальнейшая помощь, свяжитесь со мной

Смежные вопросы