Ubah durasi batas waktu Volley

191

Saya menggunakan kerangka kerja Volley baru untuk Android untuk melakukan permintaan ke server saya. Tapi itu habis sebelum mendapatkan respons, meskipun itu merespons.

Saya mencoba menambahkan kode ini:

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

di HttpClientStackkerangka Volley ke integer yang berbeda (50.000), tetapi masih keluar sebelum 50 detik.

Apakah ada cara untuk mengubah batas waktu ke nilai yang panjang?

Cissmayazz
sumber
Kemungkinan rangkap: stackoverflow.com/questions/693997/…
Adam Stelmaszczyk
21
@AdamStelmaszczyk - ini bukan duplikat karena rincian spesifik dalam kerangka kerja Volley. Pertanyaan SO yang direferensikan jika tentang penggunaan HttpClientkelas.
Michael Banzon

Jawaban:

359

Lihat Request.setRetryPolicy()dan konstruktor untuk DefaultRetryPolicy, misalnya

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));
larham1
sumber
Apakah Anda juga tahu cara mengatur prioritas permintaan?
Markus
2
@Markus menimpa Request.getPriority () untuk mengembalikan sesuatu selain 'normal'. ImageRequest melakukan ini. CATATAN: Anda harus menanyakan ini dalam pertanyaan SO terpisah.
larham1
1
Inilah tepatnya yang saya cari untuk mencegah Volley membuang permintaan saya yang membutuhkan waktu 15 detik. - Terima kasih!
slot
Saya baru saja menambahkan ini untuk permintaan POST untuk menonaktifkan coba lagi pada batas waktu. Sangat salah bahwa Pengembang Google telah memutuskan untuk menetapkan kebijakan coba lagi pada permintaan POST. Memecahkan masalah saya. Terima kasih.
Pepatah
1
@ Roon13 lihat konstruktor permintaan sampel yang baru saja ditambahkan.
larham1
226

Untuk menangani Timeout Android Volley yang perlu Anda gunakan RetryPolicy

Coba LagiPolicy

  • Volley menyediakan cara mudah untuk menerapkan RetryPolicy Anda untuk permintaan Anda.
  • Volley menetapkan Socket & ConnectionTImeout default menjadi 5 detik untuk semua permintaan.

RetryPolicy adalah antarmuka tempat Anda perlu menerapkan logika tentang bagaimana Anda ingin mencoba kembali permintaan tertentu ketika terjadi timeout.

Ini berkaitan dengan tiga parameter ini

  • Timeout - Menentukan Socket Timeout dalam millis per setiap percobaan ulang.
  • Jumlah Percobaan - Jumlah percobaan ulang yang dicoba.
  • Back Off Multiplier - Pengganda yang digunakan untuk menentukan waktu eksponensial yang diatur ke soket untuk setiap upaya coba lagi.

Misalnya Jika RetryPolicy dibuat dengan nilai-nilai ini

Timeout - 3000 ms, Jumlah Mencoba Lagi - 2, Pengali Mundur - 2.0

Coba lagi Mencoba 1:

  • time = time + (time * Back Off Multiplier);
  • waktu = 3000 + 6000 = 9000 ms
  • Socket Timeout = waktu;
  • Permintaan dikirim dengan Socket Timeout of 9 Secs

Coba lagi Mencoba 2:

  • time = time + (time * Back Off Multiplier);
  • waktu = 9000 + 18000 = 27000 ms
  • Socket Timeout = waktu;
  • Permintaan dikirim dengan Socket Timeout of 27 Secs

Jadi pada akhir Coba Lagi 2 jika masih terjadi Socket Timeout, Volley akan melempar ke TimeoutErrordalam pengendali respons Kesalahan UI Anda.

//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));
Yakiv Mospan
sumber
Terima kasih atas jawaban terperinci tentang apa yang RetryPolicysebenarnya dilakukan oleh implementasi.
dbm
5
Jawaban yang bagus @Yakiv Mospan. Tapi pada contoh Anda, waktu percobaan pertama adalah 0 + (3000 * 2), bukan 3000 + (3000 * 2). Dan yang kedua 6000 + (3000 * 2).
13KZ
13KZ, saya yakin Anda masih salah mengenai perhitungan waktu, lihat hasil edit saya dan verifikasi terhadap sumber voli
Protongun
1
Hanya pengingat bagi orang-orang yang menggunakan ini: selalu gunakan new DefaultRetryPolicy(dan pastikan untuk tidak pernah menggunakan kembali suatu RetryPolicyobjek, karena objek direferensikan melalui semua proses permintaan, dan coba lagi kenaikan ditambahkan atas nilai batas waktu objek yang sama, sehingga membuat waktu tunggu permintaan Anda di masa mendatang tumbuh tanpa batas
IG Pascual
bagaimana koneksi jabat tangan habis?
GMsoF
23

Hanya berkontribusi dengan pendekatan saya. Seperti yang sudah dijawab, RetryPolicyadalah jalan yang harus ditempuh. Tetapi jika Anda memerlukan kebijakan yang berbeda dari standar untuk semua permintaan Anda, Anda bisa mengaturnya dalam kelas Permintaan dasar, jadi Anda tidak perlu mengatur kebijakan untuk semua contoh permintaan Anda.

Sesuatu seperti ini:

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

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

Dalam kasus saya, saya memiliki GsonRequest yang memanjang dari BaseRequest ini, jadi saya tidak mengambil risiko lupa mengatur kebijakan untuk permintaan tertentu dan Anda masih bisa menimpanya jika beberapa permintaan spesifik mengharuskannya.

Androiderson
sumber
1
Ini seharusnya bekerja dengan baik? setRetryPolicy (DefaultRetryPolicy baru (1000, 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);
}
chavanNil
sumber
7
req.setRetryPolicy(new DefaultRetryPolicy(
    MY_SOCKET_TIMEOUT_MS, 
    DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
    DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

Anda dapat mengatur MY_SOCKET_TIMEOUT_MSsebagai 100. Apa pun yang Anda ingin atur ini dalam milidetik. DEFAULT_MAX_RETRIESbisa 0 default adalah 1.

Manasvi
sumber
4
int MY_SOCKET_TIMEOUT_MS=500;

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

Cara lain untuk melakukannya adalah di custom JsonObjectRequest oleh:

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

Sumber: Contoh Voli Android

Tahu
sumber
2

Solusi alternatif jika semua solusi di atas tidak bekerja untuk Anda

Secara default, Volley menetapkan batas waktu sama untuk keduanya setConnectionTimeout()dan setReadTimeout()dengan nilai dari RetryPolicy. Dalam kasus saya, Volleymelempar pengecualian batas waktu untuk potongan data besar, lihat:

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

Solusi saya adalah membuat kelas yang diperluas HttpStackdengan setReadTimeout()kebijakan saya sendiri . Kemudian gunakan saat membuat RequestQueuesebagai berikut:

Volley.newRequestQueue(mContext.getApplicationContext(), new MyHurlStack())
Bao Le
sumber
1

Saya akhirnya menambahkan metode setCurrentTimeout(int timeout)untuk RetryPolicydan implementasi itu di DefaultRetryPolicy.

Kemudian saya menambahkan setCurrentTimeout(int timeout)di kelas Permintaan dan menyebutnya.

Ini sepertinya melakukan pekerjaan.

Maaf untuk kemalasan saya dan omong-omong untuk sumber terbuka.

Cissmayazz
sumber