Итак, у меня есть этот запрос Volley PUT:

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? Пожалуйста, помогите, эта проблема сводит меня с ума ...

6
Carlos 19 Фев 2016 в 16:15

2 ответа

Лучший ответ

Вам нужно использовать 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    
        }
    });
5
herrmartell 22 Фев 2016 в 19:16

Я не совсем уверен, почему время повтора не работает с вашим кодом, я обнаружил аналогичную проблему здесь.

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

Прежде всего, вы создаете новую очередь запросов для каждого запроса, который вы делаете. Это не круто, у вас должен быть синглтон 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`

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

1
DDsix 5 Сен 2019 в 10:42