Volley, verimli HTTP istekleri yürütme ve görüntü yükleme için Google tarafından geliştirilen bir Android ağ kütüphanesidir. Kütüphane otomatik olarak bir iş parçacığı havuzunu yönetir, yanıtları önbelleğe alır ve istekleri önceliklendirir. Google, 2025'e göre, Volley karmaşık bağımlılıkları yapılandırmadan hızlı başlangıç gerektiren projeler için popüler bir seçim olmaya devam ediyor.
Anahtar Çıkarımlar
Volley, Google tarafından I/O 2013 konferansında tanıtılan Android uygulamaları için bir ağ iletişim kütüphanesidir. Volley adı “bir salvoyu” ifade eder — kütüphane, arayüz yanıt hızının önemli olduğu UI odaklı uygulamaların karakteristik özelliği olan birden çok paralel hızlı isteği yürütmek için tasarlanmıştır.
Volley, HttpURLConnection ve AsyncTask'in sorunlarına (manuel iş parçacığı yönetimi, önbellekleme eksikliği, istek önceliklendirme karmaşıklığı ve hantal kod) bir çözüm olarak oluşturuldu. Google, Volley'i “fire-and-forget” türündeki işlemler — sonucu arayüzde hemen görüntülenen küçük istekler — için bir kütüphane olarak konumlandırdı.
Volley mimarisi üç ana bileşen içerir: RequestQueue (kuyruk yöneticisi), CacheDispatcher (önbelleğe alınmış yanıtlar için iş parçacığı) ve NetworkDispatcher (ağ iş parçacıkları). Bu mimari istekleri otomatik olarak dağıtır: önce önbellek kontrol edilir ve yalnızca önbellek yoksa ağ isteği yapılır. Bu, tekrarlanan veriler için gecikmeyi %50–80 oranında azaltır.
RequestQueue, Volley'nin merkezi sınıfıdır. Request<T> nesneleri buna eklenir ve kuyruk bunları otomatik olarak iki tür iş parçacığı arasında dağıtır: CacheDispatcher (bir iş parçacığı, olası önbelleğe sahip istekleri işler) ve NetworkDispatcher (birden çok iş parçacığı, gerçek HTTP isteklerini gerçekleştirir). Varsayılan olarak Volley, 4 ağ iş parçacığı oluşturur.
Bir istek eklendiğinde, RequestQueue önbellekten sunulup sunulamayacağını kontrol eder. Önbellek güncel bir yanıt içeriyorsa, CacheDispatcher onu bir ağ isteği olmadan hemen döndürür. Önbellek güncel değilse veya yoksa, istek NetworkDispatcher'a iletilir. İstek önceliği (low, normal, high, immediate) kuyruk içindeki işlem sırasını belirler — high öncelikli istekler normal olanlardan önce işlenir.
İstek yürütüldükten sonra, sonuç Handler aracılığıyla ana iş parçacığına (UI iş parçacığı) iletilir. Volley, onResponse() ve onErrorResponse() geri çağırmalarını otomatik olarak ana iş parçacığına geçirir, böylece ek iş parçacığı değişikliği olmadan geri çağırmada doğrudan arayüz güncellenebilir. Bu, kodu basitleştirir ve bütün bir iş parçacığı hata sınıfını ortadan kaldırır.
Volley'nin bir diğer özelliği de otomatik istek yineleme kaldırmadır. Aynı URL'ye aynı parametrelerle iki özdeş GET isteği kuyruğa eklenirse, Volley bunlardan yalnızca birini yürütür ve her iki geri çağırmaya da aynı yanıtı döndürür. Bu, birden çok bileşenin bağımsız olarak aynı verileri talep ettiği ekranlar için özellikle kullanışlıdır — örneğin, hem başlık hem de ayarlar parçası tarafından aynı anda ihtiyaç duyulan bir kullanıcı profili.
Her istek bir dizi adımdan geçer: Request oluşturma, RequestQueue'ya ekleme, önbelleği kontrol etme (CacheDispatcher), HTTP isteğini yürütme (NetworkDispatcher), Response.Listener aracılığıyla yanıtı ayrıştırma, sonucu UI iş parçacığına iletme. Bir istek iptal edildiğinde (cancel), RequestQueue onu kuyruktan kaldırır ve geri çağırmaların çağrılmasını önler.
Volley ayrıca başarısızlıklarda yeniden deneme sayısını belirleyen RetryPolicy'yi de destekler. DefaultRetryPolicy varsayılan olarak 2,5 saniyelik bir zaman aşımıyla bir yeniden deneme yapar. Kararsız bağlantılar için yeniden deneme sayısı 3'e ve zaman aşımı 10 saniyeye çıkarılabilir. Özel bir RetryPolicy, getCurrentTimeout, getCurrentRetryCount ve retry yöntemleriyle RetryPolicy arayüzü aracılığıyla uygulanır.
Volley, yaygın veri biçimleri için hazır istek türleri sağlar. Her tür, soyut sınıf Request<T>'yi uygular ve yanıtı ayrıştırmak için bir yöntem tanımlar. Özel biçimler için, parseNetworkResponse yöntemini geçersiz kılarak kendi türünüzü oluşturabilirsiniz.
| İstek türü | Dönüş türü | Amaç |
|---|---|---|
| StringRequest | String | Ham metin yanıtı alma |
| JsonObjectRequest | JSONObject | JSON nesnesini ayrıştırma |
| JsonArrayRequest | JSONArray | JSON dizisini ayrıştırma |
| ImageRequest | Bitmap | Görüntü yükleme ve kod çözme |
| ClearCacheRequest | — | Volley önbelleğini temizleme |
Gson veya Kotlinx Serialization ile çalışmak için, parseNetworkResponse'te seçilen ayrıştırıcıyı kullanan özel bir Request<T> oluşturabilirsiniz. Bu, manuel JSONObject ayrıştırmasını atlayarak doğrudan tür belirtilmiş nesneler almanızı sağlar. Bu yaklaşım, halihazırda Gson veya Moshi aracılığıyla serileştirme kullanan projeler için özellikle kullanışlıdır.
Veri göndermek için Volley üç gövde türünü destekler: JSONObject (POST yöntemiyle JsonObjectRequest aracılığıyla), Form-encoded (kurucuda HashMap<String, String> aracılığıyla) ve Multipart (özel bir MultipartRequest aracılığıyla). Multipart istekleri görüntü ve dosya yüklemek için kullanışlıdır ancak OkHttp veya Dio'nun aksine Volley'nin multipart/form-data için yerleşik desteği olmadığından manuel uygulama gerektirir.
Volley'nin sınırlamaları, büyük yanıtlarla çalışırken belirginleşir. Volley, geri çağırmaya geçirmeden önce yanıtın tamamını belleğe yükler, bu da 10–20 MB'tan büyük JSON dosyaları için OutOfMemoryError'a neden olabilir. Büyük dosyaları indirmek için Volley uygun değildir — DownloadManager veya akışlı ResponseBody ile OkHttp kullanın. Volley ayrıca kesintiye uğrayan indirmeleri sürdürmeyi (Range başlığı) desteklemez ve gerçek zamanlı olarak Server-Sent Events veya WebSocket gibi akış protokolleriyle çalışmaz.
Temel bir örneğe bakalım — bir sunucudan veri almak için StringRequest. Önce, Volley.newRequestQueue(context) aracılığıyla bir RequestQueue oluşturulur. Ardından, bir URL ve başarı ve hata geri çağırmalarıyla bir istek oluşturulur.
val queue = Volley.newRequestQueue(context)
val request = StringRequest(
Request.Method.GET,
"https://api.github.com/users/octocat",
{ response ->
println("Yanıt: $response")
},
{ error ->
println("Hata: ${error.message}")
}
)
queue.add(request)
JSON isteği için, yanıtı otomatik olarak bir JSONObject'e ayrıştıran JsonObjectRequest kullanılır. Volley, GET ve POST isteklerini destekler. POST için, istek gövdesinde bir JSONObject iletilir.
val jsonBody = JSONObject()
jsonBody.put("name", "New Repo")
jsonBody.put("description", "Created via Volley")
val request = JsonObjectRequest(
Request.Method.POST,
"https://api.github.com/user/repos",
jsonBody,
{ response ->
println("Oluşturuldu: ${response.getString("id")}")
},
{ println("Hata: $it") }
)
queue.add(request)
Bir isteği iptal etmek için cancel() yöntemi veya etikete göre grup iptali kullanılır. İptal edildiğinde, Volley ne onResponse'u ne de onErrorResponse'u çağırmaz, bu da ekrandan çıktıktan sonra arayüz güncellemelerini önler. Bu, Activity ve Fragment'te bellek sızıntılarını önlemek için önemlidir.
request.tag = "profile_request"
queue.add(request)
// Ekrandan çıkarken iptal
queue.cancelAll("profile_request")
ImageLoader, görüntü yüklemek için optimize edilmiş, RequestQueue üzerinde bir sarmalayıcı sınıftır. Bellek önbelleğini (LruCache) destekler ve RecyclerView listelerinde ImageView yeniden kullanıldığında istekleri otomatik olarak iptal eder. ImageLoader ayrıca görüntüleri View boyutuna sığdırmak için ölçeklendirerek bellekten tasarruf sağlar.
NetworkImageView, ImageLoader ile entegre olan ve yüklemeyi otomatik olarak yöneten özel bir View'dir: yükleme sırasında bir yer tutucu gösterir, başarısızlıkta bunu bir hatayla değiştirir ve View ekrandan ayrıldığında isteği iptal eder. DefaultImageUrlLoader, URL'ye göre bir görüntü yükler ve hızlı yeniden görüntüleme için LruCache'te saklar.
ImageLoader'ı kullanmak için, ImageLoader(queue, ImageCache) aracılığıyla bir örnek oluşturmanız yeterlidir; burada ImageCache, içinde LruCache bulunan ImageCache arayüzünün bir uygulamasıdır. XML düzenindeki NetworkImageView, setImageUrl() yöntemi aracılığıyla ImageLoader'a bağlanır ve yer tutucuları ve hataları işlemek için ek kod olmadan tüm yükleme tamamen otomatik olarak gerçekleşir.
Her Activity'de RequestQueue oluşturmak, iş parçacığı tekrarına ve önbellek karışıklığına yol açan yaygın bir hatadır. RequestQueue'nin Application'da bir kez veya bir singleton sınıfı aracılığıyla oluşturulması önerilir. Aksi takdirde, her ekranın kendi iş parçacığı havuzu olur ve önbellek her kuyruk için ayrı ayrı saklanır.
Ekran döndürmede istek iptalini görmezden gelmek. Yapılandırma değiştiğinde, Activity yeniden oluşturulur ve eski Activity'nin geri çağırmaları bellekte kalmaya devam eder. Bu, sızıntılara ve yok edilmiş bir View'ı güncelleme girişimlerine yol açar. Her zaman Activity'ye özgü bir etiketle onStop() içinde cancelAll() aracılığıyla istekleri iptal edin.
Volley, HTTP/2 ve eşyordamları (coroutine) desteklemez — bu bir kullanım hatası değil, mimari bir sınırlamadır. Volley 2013'te oluşturuldu ve modern protokolleri ve Kotlin eşyordamlarını desteklemez. Yeni projeler için Google, Retrofit + OkHttp kullanılmasını önerir. Volley yalnızca eski projeleri desteklemek veya minimum ağ gereksinimi olan basit uygulamalar için uygundur.
Sıkça sorulan sorular
Volley yeni projeler için güncelliğini yitirdi — Google, 2017'den beri kütüphaneyi güncellemedi. Modern uygulamalar için Retrofit + OkHttp veya Ktor Client kullanın. Volley yalnızca mevcut eski kodu desteklemek için veya minimum ağ görevleri olan basit eğitim projelerinde kullanılabilir.
Modern teknolojiler için destek eksikliği: HTTP/2, Kotlin eşyordamları, çok platformlu geliştirme ve tür belirtilmiş serileştirme. Volley, türler olmadan JSONObject ve JSONArray kullanır, bu da JSON yapısı beklentilerle eşleşmediğinde çalışma zamanı hatalarına yol açar.
ImageLoader ve NetworkImageView aracılığıyla. ImageLoader, görüntülerin bellek önbelleğe alınması için LruCache kullanır ve görüntüler yeniden kullanıldığında istekleri otomatik olarak iptal eder. NetworkImageView, yükleme sırasında bir yer tutucu gösterir ve bunu yüklenen görüntü veya bir hata göstergesiyle değiştirir.
Teknik olarak evet — Volley geri çağırmaları üzerinde bir suspendCoroutine { } sarmalayıcısı aracılığıyla. Ancak bunun bir avantajı yoktur çünkü Volley, eşyordam iptaline dayalı iptali desteklemez ve doğrudan Dispatchers.IO ile çalışmaz. Yerel eşyordam desteği olan Ktor Client'ı kullanmak daha iyidir.
Zaman aşımı RetryPolicy aracılığıyla yapılandırılır. Varsayılan olarak, DefaultRetryPolicy 2,5 saniyelik bir zaman aşımı ve bir yeniden deneme kullanır. Parametreleri değiştirmek için: request.retryPolicy = DefaultRetryPolicy(10000, 1, 1.0f) — 10 saniye zaman aşımı, bir deneme.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun