Thay đổi thời gian chờ của Volley


190

Tôi sử dụng khung Volley mới cho Android để thực hiện yêu cầu đến máy chủ của mình. Nhưng nó hết thời gian chờ trước khi nhận được phản hồi, mặc dù nó phản hồi.

Tôi đã thử thêm mã này:

HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
HttpConnectionParams.setSoTimeout(httpParams, timeoutMs);

trong HttpClientStackkhung Volley thành một số nguyên khác (50000), nhưng nó vẫn hết thời gian trước 50 giây.

Có cách nào để thay đổi thời gian chờ thành giá trị dài không?



21
@AdamStelmaszchot - đây sẽ không phải là một bản sao vì nó là về các chi tiết cụ thể trong khung Volley. Câu hỏi SO được tham chiếu nếu về việc sử dụng HttpClientlớp.
Michael Banzon

Câu trả lời:


357

Xem Request.setRetryPolicy()và các nhà xây dựng cho DefaultRetryPolicy, ví dụ

JsonObjectRequest myRequest = new JsonObjectRequest(Method.GET,
        url, null,
        new Response.Listener<JSONObject>() {

            @Override
            public void onResponse(JSONObject response) {
                Log.d(TAG, response.toString());
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d(TAG, "Error: " + error.getMessage());
            }
});

myRequest.setRetryPolicy(new DefaultRetryPolicy(
        MY_SOCKET_TIMEOUT_MS, 
        DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
        DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

Bạn có biết làm thế nào để thiết lập mức độ ưu tiên của một yêu cầu?
Markus

2
@Markus ghi đè Request.getP Warriority () để trả lại một cái gì đó ngoài 'bình thường'. ImageRequest thực hiện điều này. LƯU Ý: bạn nên hỏi điều này trong một câu hỏi SO riêng biệt.
larham1

1
Đây chính xác là những gì tôi đang tìm kiếm để ngăn Volley loại bỏ yêu cầu của tôi mất 15 giây. - Thanx!
slott

Tôi vừa thêm cái này cho các yêu cầu POST để tắt thử lại khi hết thời gian. Thật sai lầm khi các nhà phát triển của Google quyết định thiết lập chính sách thử lại đối với các yêu cầu POST. Giải quyết vấn đề của tôi. Cảm ơn.
Tục ngữ

1
@ Roon13 xem hàm tạo yêu cầu mẫu vừa được thêm.
larham1

226

Để xử lý Android Volley Timeout, bạn cần sử dụng RetryPolicy

RetryPolicy

  • Volley cung cấp một cách dễ dàng để thực hiện RetryPolicy cho các yêu cầu của bạn.
  • Volley đặt socket & ConnectionTImeout mặc định thành 5 giây cho tất cả các yêu cầu.

RetryPolicy là một giao diện nơi bạn cần triển khai logic của mình về cách bạn muốn thử lại một yêu cầu cụ thể khi hết thời gian chờ.

Nó liên quan đến ba tham số này

  • Hết giờ - Chỉ định Hết thời gian chờ tính bằng mili giây cho mỗi lần thử lại.
  • Số lần thử lại - Số lần thử lại được thử.
  • Back Off Multiplier - Một hệ số nhân được sử dụng để xác định thời gian theo cấp số nhân được đặt thành ổ cắm cho mỗi lần thử lại.

Dành cho người cũ Nếu RetryPolicy được tạo với các giá trị này

Hết thời gian - 3000 ms, Nhiều lần thử lại - 2, Tắt hệ số nhân - 2.0

Thử lại 1:

  • time = time + (time * Back Off Multiplier);
  • thời gian = 3000 + 6000 = 9000ms
  • Hết thời gian chờ = thời gian;
  • Yêu cầu được gửi đi với thời gian chờ của socket là 9 giây

Thử lại 2:

  • time = time + (time * Back Off Multiplier);
  • thời gian = 9000 + 18000 = 27000ms
  • Hết thời gian chờ = thời gian;
  • Yêu cầu được gửi đi với thời gian chờ là 27 giây

Vì vậy, khi kết thúc Thử lại 2 nếu vẫn xảy ra Hết thời gian chờ, Volley sẽ ném TimeoutErrorvào trình xử lý phản hồi Lỗi UI của bạn.

//Set a retry policy in case of SocketTimeout & ConnectionTimeout Exceptions. 
//Volley does retry for you if you have specified the policy.
jsonObjRequest.setRetryPolicy(new DefaultRetryPolicy(5000, 
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

Cảm ơn cho một câu trả lời chi tiết về những gì RetryPolicythực hiện thực sự.
dbm

5
Câu trả lời hay @Yakiv Mospan. Nhưng trong ví dụ của bạn, thời gian của lần thử đầu tiên là 0 + (3000 * 2) thay vì 3000 + (3000 * 2). Và cái thứ hai 6000 + (3000 * 2).
13KZ

13KZ, tôi tin rằng bạn vẫn sai về tính toán thời gian, hãy xem bản chỉnh sửa của tôi và xác minh dựa vào nguồn bóng chuyền
Protongun

1
Chỉ cần một lời nhắc nhở cho những người sử dụng điều này: luôn luôn sử dụng new DefaultRetryPolicy(và đảm bảo không bao giờ sử dụng lại một RetryPolicyđối tượng, vì đối tượng được tham chiếu qua tất cả quy trình yêu cầu và gia tăng thử lại được thêm vào cùng một giá trị hết thời gian của đối tượng, do đó làm cho thời gian chờ yêu cầu trong tương lai của bạn tăng lên vô hạn
IG Pascual

Làm thế nào là thời gian chờ bắt tay kết nối?
GMsoF

23

Chỉ để đóng góp với cách tiếp cận của tôi. Như đã trả lời, RetryPolicylà con đường để đi. Nhưng nếu bạn cần một chính sách khác với mặc định cho tất cả các yêu cầu của mình, bạn có thể đặt chính sách đó trong lớp Yêu cầu cơ sở, do đó bạn không cần đặt chính sách cho tất cả các phiên bản yêu cầu của mình.

Một cái gì đó như thế này:

public class BaseRequest<T> extends Request<T> {

    public BaseRequest(int method, String url, Response.ErrorListener listener) {
        super(method, url, listener);
        setRetryPolicy(getMyOwnDefaultRetryPolicy());
    }
}

Trong trường hợp của tôi, tôi có một GsonRequest mở rộng từ BaseRequest này, vì vậy tôi không gặp rủi ro khi quên đặt chính sách cho một yêu cầu cụ thể và bạn vẫn có thể ghi đè lên nếu yêu cầu cụ thể nào đó yêu cầu.


1
Điều này nên làm việc phải không? setR temPolicy (new DefaultR temPolicy (1000, DefaultR temPolicy.DEFAULT_MAX_RETRIES, DefaultR temPolicy.DEFAULT_BACKOFF_MULT));
LOGiah 5/2/2015

12
/**
 * @param request
 * @param <T>
 */
public <T> void addToRequestQueue(Request<T> request) {

    request.setRetryPolicy(new DefaultRetryPolicy(
            MY_SOCKET_TIMEOUT_MS,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

    getRequestQueue().add(request);
}

7
req.setRetryPolicy(new DefaultRetryPolicy(
    MY_SOCKET_TIMEOUT_MS, 
    DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
    DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

Bạn có thể đặt MY_SOCKET_TIMEOUT_MSlà 100. Bất cứ điều gì bạn muốn đặt này là tính bằng mili giây. DEFAULT_MAX_RETRIEScó thể là 0 mặc định là 1.


4
int MY_SOCKET_TIMEOUT_MS=500;

 stringRequest.setRetryPolicy(new DefaultRetryPolicy(
                MY_SOCKET_TIMEOUT_MS,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

3

Một cách khác để làm điều đó là trong JsonObjectRequest tùy chỉnh bằng cách:

@Override
public RetryPolicy getRetryPolicy() {
    // here you can write a custom retry policy and return it
    return super.getRetryPolicy();
}

Nguồn: Ví dụ về bóng chuyền Android


2

Giải pháp thay thế nếu tất cả các giải pháp trên không hiệu quả với bạn

Theo mặc định, Volley đặt thời gian chờ bằng nhau cho cả hai setConnectionTimeout()setReadTimeout()với giá trị từ RetryPolicy. Trong trường hợp của tôi, Volleyném ngoại lệ thời gian chờ cho khối dữ liệu lớn xem:

com.android.volley.toolbox.HurlStack.openConnection(). 

Giải pháp của tôi là tạo ra một lớp học mở rộng HttpStackvới setReadTimeout()chính sách của riêng tôi . Sau đó sử dụng nó khi tạo RequestQueuenhư sau:

Volley.newRequestQueue(mContext.getApplicationContext(), new MyHurlStack())

1

Tôi đã kết thúc việc thêm một phương thức setCurrentTimeout(int timeout)vào RetryPolicyvà thực hiện nó DefaultRetryPolicy.

Sau đó, tôi đã thêm một setCurrentTimeout(int timeout)trong lớp Yêu cầu và gọi nó.

Điều này dường như để làm công việc.

Xin lỗi vì sự lười biếng của tôi bằng cách này và hoan hô cho nguồn mở.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.