เปลี่ยนระยะเวลาการหมดเวลาวอลเล่ย์


191

ฉันใช้กรอบการทำงานใหม่ของ Volley สำหรับ Android เพื่อส่งคำขอไปยังเซิร์ฟเวอร์ของฉัน แต่มันจะหมดเวลาก่อนที่จะได้รับคำตอบแม้ว่ามันจะตอบสนอง

ฉันพยายามเพิ่มรหัสนี้:

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

ในHttpClientStackเฟรมเวิร์กของ Volley ให้เป็นจำนวนเต็มที่แตกต่างกัน (50000) แต่ยังคงหมดเวลาก่อน 50 วินาที

มีวิธีการเปลี่ยนการหมดเวลาเป็นค่ายาวหรือไม่?


สำเนาซ้ำที่เป็นไปได้: stackoverflow.com/questions/693997/…
Adam Stelmaszczyk

21
@ AdamStelmaszczyk - นี่จะไม่ซ้ำกันเนื่องจากเป็นรายละเอียดเฉพาะในกรอบการทำงานของ Volley คำถาม SO ที่อ้างอิงถ้าเกี่ยวกับการใช้HttpClientคลาส
Michael Banzon

คำตอบ:


359

ดูRequest.setRetryPolicy()และตัวสร้างสำหรับDefaultRetryPolicyเช่น

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));

คุณรู้วิธีตั้งลำดับความสำคัญของคำขอหรือไม่?
Markus

2
@Markus ลบล้าง Request.getPriority () เพื่อส่งคืนสิ่งที่นอกเหนือจาก 'ปกติ' ImageRequest ทำเช่นนี้ หมายเหตุ: คุณควรถามคำถามนี้ด้วยคำถาม SO แยกต่างหาก
larham1

1
นี่คือสิ่งที่ฉันกำลังมองหาเพื่อป้องกันไม่ให้วอลเล่ย์ยกเลิกคำขอของฉันซึ่งใช้เวลา 15 วินาที - Thanx!
slott

ฉันเพิ่งเพิ่มสิ่งนี้สำหรับคำขอ POST เพื่อปิดใช้งานลองอีกครั้งเมื่อหมดเวลา มันผิดอย่างไม่น่าเชื่อที่ Google Developers ได้ตัดสินใจที่จะกำหนดนโยบายลองอีกครั้งในคำขอ POST แก้ไขปัญหาของฉัน ขอบคุณ
Proverbio

1
@ Roon13 ดูตัวสร้างคำขอตัวอย่างที่เพิ่งเพิ่มเข้าไป
larham1

226

ในการจัดการ Android Volley Timeout คุณต้องใช้ RetryPolicy

RetryPolicy

  • วอลเล่มอบวิธีที่ง่ายในการปรับใช้ RetryPolicy ของคุณสำหรับคำขอของคุณ
  • วอลเล่ย์ตั้งซ็อกเก็ตและการเชื่อมต่อเริ่มต้น 5 นาทีสำหรับคำขอทั้งหมด

RetryPolicy เป็นอินเทอร์เฟซที่คุณต้องการใช้ตรรกะของคุณว่าคุณต้องการลองคำขอเฉพาะเมื่อเกิดการหมดเวลา

มันเกี่ยวข้องกับพารามิเตอร์ทั้งสามนี้

  • การหมดเวลา - ระบุการหมดเวลาซ็อกเก็ตในหน่วยมิลลิวินาทีต่อทุกครั้งที่ลองใหม่
  • Number Of Retries - จำนวนครั้งที่พยายามลองใหม่
  • Back Off Multiplier - ตัวคูณที่ใช้เพื่อกำหนดเวลาเอ็กซ์โพเนนเชียลที่ตั้งค่าเป็นซ็อกเก็ตสำหรับความพยายามทุกครั้ง

สำหรับอดีต หาก RetryPolicy ถูกสร้างขึ้นด้วยค่าเหล่านี้

หมดเวลา - 3000 ms, จำนวนครั้งที่ลองใหม่ - 2, ตัวคูณย้อนกลับ - 2.0

ลองใหม่อีกครั้ง 1:

  • time = time + (เวลา * Back Off Multiplier);
  • เวลา = 3000 + 6000 = 9000ms
  • Socket Timeout = time;
  • คำขอส่งไปพร้อมกับ Socket Timeout 9 วินาที

ลองใหม่อีกครั้ง 2:

  • time = time + (เวลา * Back Off Multiplier);
  • เวลา = 9000 + 18000 = 27000ms
  • Socket Timeout = time;
  • คำขอทำการจัดส่งด้วย Socket Timeout 27 Secs

ดังนั้นในตอนท้ายของRetry Attempt 2หากยังคงเกิด Socket Timeout เกิดขึ้น Volley จะส่งTimeoutErrorตัวจัดการการตอบสนองข้อผิดพลาด UI ของคุณ

//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));

ขอขอบคุณสำหรับคำตอบโดยละเอียดเกี่ยวกับการRetryPolicyใช้งานจริง
dbm

5
คำตอบที่ดี @Yakiv Mospan แต่ในตัวอย่างของคุณเวลาของความพยายามครั้งแรกคือ 0 + (3000 * 2) แทน 3000 + (3000 * 2) และอันที่สอง 6000 + (3000 * 2)
13KZ

13KZ ฉันเชื่อว่าคุณยังผิดเกี่ยวกับการคำนวณเวลาดูการแก้ไขของฉันและตรวจสอบกับแหล่งวอลเลย์
Protongun

1
เพียงแค่เตือนสำหรับคนที่ใช้นี้: เสมอใช้new DefaultRetryPolicy(และให้แน่ใจว่าจะไม่เคยนำมาใช้ใหม่RetryPolicyวัตถุเป็นวัตถุมีการอ้างอิงผ่านทุกขั้นตอนการขอและการเพิ่มขึ้นลองใหม่อีกครั้งที่มีการเพิ่มสูงกว่ามูลค่าวัตถุหมดเวลาเดียวกันจึงทำให้หมดเวลาการร้องขอในอนาคตของคุณเจริญเติบโตเพียบ
IG Pascual

การหมดเวลาจับมือการเชื่อมต่อเป็นอย่างไร
GMsoF

23

เพียงเพื่อมีส่วนร่วมกับวิธีการของฉัน ดังที่ได้ตอบไปแล้วRetryPolicyเป็นหนทางที่จะไป แต่ถ้าคุณต้องการนโยบายที่แตกต่างจากค่าเริ่มต้นสำหรับคำขอทั้งหมดของคุณคุณสามารถตั้งค่าได้ในคลาส Request Base ดังนั้นคุณไม่จำเป็นต้องตั้งนโยบายสำหรับอินสแตนซ์ทั้งหมดของคำขอของคุณ

บางสิ่งเช่นนี้

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

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

ในกรณีของฉันฉันมี GsonRequest ซึ่งขยายจาก BaseRequest นี้ดังนั้นฉันจึงไม่เสี่ยงที่จะลืมกำหนดนโยบายสำหรับคำขอเฉพาะและคุณยังสามารถแทนที่ได้หากมีคำขอเฉพาะที่ต้องการ


1
สิ่งนี้จะใช้ได้ใช่ไหม setRetryPolicy (ใหม่ DefaultRetryPolicy (1,000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
LOG_TAG

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));

คุณสามารถตั้งค่าMY_SOCKET_TIMEOUT_MSเป็น 100 สิ่งใดก็ตามที่คุณต้องการตั้งค่านี้เป็นมิลลิวินาที DEFAULT_MAX_RETRIESสามารถเป็น 0 ค่าเริ่มต้นคือ 1


4
int MY_SOCKET_TIMEOUT_MS=500;

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


2

ทางเลือกอื่นหากโซลูชันด้านบนทั้งหมดไม่ได้ผลสำหรับคุณ

โดยค่าเริ่มต้นวอลเล่ย์ตั้งหมดเวลาเท่าเทียมกันสำหรับทั้งสองsetConnectionTimeout()และมีค่าจากsetReadTimeout() RetryPolicyในกรณีของฉันVolleyโยนข้อยกเว้นการหมดเวลาสำหรับกลุ่มข้อมูลขนาดใหญ่ดู:

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

โซลูชันของฉันคือการสร้างคลาสที่ครอบคลุมHttpStackกับsetReadTimeout()นโยบายของฉันเอง จากนั้นใช้เมื่อสร้างRequestQueueดังต่อไปนี้:

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

1

ฉันสิ้นสุดขึ้นการเพิ่มวิธีการsetCurrentTimeout(int timeout)ไปและก็ดำเนินการในRetryPolicyDefaultRetryPolicy

จากนั้นฉันเพิ่มsetCurrentTimeout(int timeout)ในคลาสคำขอและเรียกมันว่า

ดูเหมือนว่าจะทำงาน

ขออภัยสำหรับความเกียจคร้านของฉันตามวิธีและไชโยสำหรับโอเพนซอร์ส

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.