Volley — Android üçün Google tərəfindən hazırlanmış, HTTP sorğularını və şəkillərin yüklənməsini səmərəli şəkildə yerinə yetirən şəbəkə kitabxanasıdır. Kitabxana avtomatik olaraq axın hovuzunu idarə edir, cavabları keşləyir və sorğuları prioritetləşdirir. Google, 2025 məlumatına görə, Volley mürəkkəb asılılıqları konfiqurasiya etmədən sürətli başlanğıc tələb edən layihələr üçün populyar seçim olaraq qalır.
Əsas məqamlar
Volley — Google tərəfindən I/O 2013 konfransında təqdim edilmiş Android tətbiqlərində şəbəkə əlaqəsi üçün kitabxanadır. Volley adı “salvo” mənasını verir — kitabxana interfeysin cavab sürətinin vacib olduğu UI yönümlü tətbiqlər üçün xarakterik olan çoxsaylı paralel sürətli sorğuları yerinə yetirmək üçün nəzərdə tutulub.
Volley HttpURLConnection və AsyncTask problemlərinin həlli kimi yaradılmışdır: axınların əl ilə idarə edilməsi, keşləmənin olmaması, sorğuların prioritetləşdirilməsinin çətinliyi və həcmli kod. Google Volley-ni “fire-and-forget” tipli əməliyyatlar üçün kitabxana kimi təqdim etmişdir — nəticəsi dərhal interfeysdə göstərilən kiçik sorğular.
Volley memarlığı üç əsas komponentdən ibarətdir: RequestQueue (növbə meneceri), CacheDispatcher (keşlənmiş cavablar üçün axın) və NetworkDispatcher (şəbəkə axınları). Bu memarlıq sorğuları avtomatik olaraq bölüşdürür: əvvəlcə keş yoxlanılır və yalnız olmadıqda şəbəkə sorğusu yerinə yetirilir. Bu, təkrarlanan məlumatlar üçün gecikməni 50–80% azaldır.
RequestQueue — Volley-in mərkəzi sinfi. Ona Request<T> obyektləri əlavə edilir və növbə onları avtomatik olaraq iki növ axına bölüşdürür: CacheDispatcher (bir axın, mümkün keşi olan sorğuları emal edir) və NetworkDispatcher (bir neçə axın, real HTTP sorğularını yerinə yetirir). Susmaya görə Volley 4 şəbəkə axını yaradır.
Sorğu əlavə edildikdə RequestQueue onun keşdən xidmət edilə biləcəyini yoxlayır. Əgər keş aktual cavab ehtiva edirsə, CacheDispatcher onu dərhal qaytarır, şəbəkə sorğusu olmadan. Keş köhnəlmiş və ya yoxdursa, sorğu NetworkDispatcher-ə ötürülür. Sorğu prioriteti (low, normal, high, immediate) növbə daxilində emal qaydasını müəyyən edir — high prioritetli sorğular normal-dan əvvəl işlənir.
Sorğu yerinə yetirildikdən sonra nəticə Handler vasitəsilə əsas axına (UI thread) çatdırılır. Volley avtomatik olaraq onResponse() və onErrorResponse() callback-lərini əsas axına keçirir, buna görə interfeysi birbaşa callback-də əlavə keçidlər olmadan yeniləmək olar. Bu, kodu sadələşdirir və axınlarla bağlı səhvlərin bütün sinfini aradan qaldırır.
Volley-in digər xüsusiyyəti sorğuların avtomatik deduplikasiyasıdır. Əgər növbəyə eyni URL-ə eyni parametrlərlə iki eyni GET sorğusu əlavə edilərsə, Volley onlardan yalnız birini yerinə yetirir və eyni cavabı hər iki callback-ə qaytarır. Bu, bir neçə komponentin müstəqil olaraq eyni məlumatları tələb etdiyi ekranlar üçün xüsusilə faydalıdır — məsələn, eyni zamanda həm başlığa, həm də parametrləri olan fraqmentə lazım olan istifadəçi profili.
Hər bir sorğu addımlar ardıcıllığından keçir: Request yaradılması, RequestQueue-ə əlavə edilməsi, keş yoxlanışı (CacheDispatcher), HTTP sorğusunun yerinə yetirilməsi (NetworkDispatcher), Response.Listener vasitəsilə cavabın pars edilməsi, nəticənin UI axınına çatdırılması. Sorğu ləğv edildikdə (cancel) RequestQueue onu növbədən silir və callback-lərin çağırılmasının qarşısını alır.
Volley həmçinin RetryPolicy-ni dəstəkləyir, hansı ki, nasazlıqlar zamanı təkrar cəhdlərin sayını müəyyən edir. DefaultRetryPolicy susmaya görə 2.5 saniyə timeout ilə bir təkrar cəhd edir. Qeyri-sabit birləşmələr üçün təkrar sayını 3-ə, timeout-u isə 10 saniyəyə qədər artırmaq olar. Xüsusi RetryPolicy getCurrentTimeout, getCurrentRetryCount və retry metodları olan RetryPolicy interfeysi vasitəsilə tətbiq edilir.
Volley məlumatların məşhur formatları üçün hazır sorğu növləri təqdim edir. Hər bir növ Request<T> abstrakt sinfini tətbiq edir və cavabın pars edilməsi üsulunu müəyyən edir. Xüsusi formatlar üçün parseNetworkResponse metodunu əvəz etməklə öz növünüzü yarada bilərsiniz.
| Sorğu növü | Qaytarılan növ | Təyinat |
|---|---|---|
| StringRequest | String | Xam mətn cavabının alınması |
| JsonObjectRequest | JSONObject | JSON obyektinin pars edilməsi |
| JsonArrayRequest | JSONArray | JSON massivinin pars edilməsi |
| ImageRequest | Bitmap | Şəklin yüklənməsi və dekodlaşdırılması |
| ClearCacheRequest | — | Volley keşinin təmizlənməsi |
Gson və ya Kotlinx Serialization ilə işləmək üçün parseNetworkResponse-də seçilmiş parseri istifadə edən xüsusi Request<T> yarada bilərsiniz. Bu, JSONObject-in əl ilə pars edilməsini keçərək birbaşa tipləşdirilmiş obyektlər əldə etməyə imkan verir. Bu yanaşma artıq Gson və ya Moshi vasitəsilə serializasiyadan istifadə edən layihələr üçün xüsusilə faydalıdır.
Məlumat göndərmək üçün Volley üç növ bədəni dəstəkləyir: JSONObject (POST metodu ilə JsonObjectRequest vasitəsilə), Form-encoded (konstruktorda HashMap<String, String> vasitəsilə) və Multipart (xüsusi MultipartRequest vasitəsilə). Multipart sorğuları şəkillərin və faylların yüklənməsi üçün faydalıdır, lakin əl ilə tətbiq tələb edir, çünki Volley OkHttp və ya Dio-dan fərqli olaraq multipart/form-data üçün daxili dəstəyə malik deyil.
Volley-in məhdudiyyətləri böyük cavablarla işləyərkən nəzərə çarpır. Volley cavabı callback-ə ötürməzdən əvvəl bütünlüklə yaddaşa yükləyir, bu da 10–20 MB-dan böyük JSON faylları üçün OutOfMemoryError-a səbəb ola bilər. Böyük faylları yükləmək üçün Volley uyğun deyil — DownloadManager və ya axınlı ResponseBody ilə OkHttp istifadə edin. Volley həmçinin kəsilmiş yükləmələrin davam etdirilməsini (Range header) dəstəkləmir və real vaxt rejimində Server-Sent Events və ya WebSocket kimi axın protokolları ilə işləmir.
Əsas nümunəni nəzərdən keçirək — serverdən məlumat almaq üçün StringRequest. Əvvəlcə Volley.newRequestQueue(context) vasitəsilə RequestQueue yaradılır. Sonra URL və uğur/xəta callback-ləri ilə sorğu formalaşdırılır.
val queue = Volley.newRequestQueue(context)
val request = StringRequest(
Request.Method.GET,
"https://api.github.com/users/octocat",
{ response ->
println("Cavab: $response")
},
{ error ->
println("Xəta: ${error.message}")
}
)
queue.add(request)
JSON sorğusu üçün cavabı avtomatik olaraq JSONObject-ə pars edən JsonObjectRequest istifadə olunur. Volley GET və POST sorğularını dəstəkləyir. POST üçün sorğunun gövdəsində JSONObject ötürülür.
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("Yaradıldı: ${response.getString("id")}")
},
{ println("Xəta: $it") }
)
queue.add(request)
Sorğunu ləğv etmək üçün cancel() metodu və ya teq üzrə qrup ləğvi istifadə olunur. Ləğv edildikdə Volley nə onResponse, nə də onErrorResponse çağırmır, bu da ekrandan çıxdıqdan sonra interfeysin yenilənməsinin qarşısını alır. Bu, Activity və Fragment-də yaddaş sızmalarının qarşısını almaq üçün vacibdir.
request.tag = "profile_request"
queue.add(request)
// Ekrandan çıxanda ləğv et
queue.cancelAll("profile_request")
ImageLoader — RequestQueue üzərində şəkillərin yüklənməsi üçün optimallaşdırılmış sarma sinifidir. O, yaddaş keşini (LruCache) dəstəkləyir və RecyclerView siyahılarında ImageView təkrar istifadə edildikdə sorğuları avtomatik ləğv edir. ImageLoader həmçinin şəkilləri View ölçüsünə uyğun miqyaslayaraq yaddaşa qənaət edir.
NetworkImageView — ImageLoader ilə inteqrasiya olunan və yükləməni avtomatik idarə edən xüsusi View-dir: yükləmə zamanı placeholder qoyur, nasazlıqda xəta ilə əvəz edir və View ekrandan çıxdıqda sorğunu ləğv edir. DefaultImageUrlLoader şəkili URL üzrə yükləyir və sürətli təkrar göstərmək üçün LruCache-də saxlayır.
ImageLoader istifadə etmək üçün ImageLoader(queue, ImageCache) vasitəsilə nümunə yaratmaq kifayətdir, burada ImageCache daxilində LruCache olan ImageCache interfeysinin tətbiqidir. XML-də NetworkImageView setImageUrl() metodu vasitəsilə ImageLoader-ə bağlanır və bütün yükləmə placeholder və xətaların işlənməsi üçün əlavə kod olmadan tam avtomatik baş verir.
Hər Activity-də RequestQueue yaratmaq — axınların təkrarlanmasına və keşdə qarışıqlığa səbəb olan ümumi səhvdir. RequestQueue-ni bir dəfə Application-də və ya sinqlton sinfi vasitəsilə yaratmaq tövsiyə olunur. Əks halda hər ekran öz axın hovuzuna sahib olacaq və keş hər növbə üçün ayrı saxlanılacaq.
Ekran döndərildikdə sorğuların ləğvinin nəzərə alınmaması. Konfiqurasiya dəyişikliyi zamanı Activity yenidən yaradılır və köhnə Activity-nin callback-ləri yaddaşda qalır. Bu, sızmaya və məhv edilmiş View-in yenilənməsi cəhdinə gətirib çıxarır. Həmişə onStop() daxilində Activity üçün xüsusi teq ilə cancelAll() vasitəsilə sorğuları ləğv edin.
Volley HTTP/2 və korutinləri dəstəkləmir — bu istifadə xətası deyil, memarlıq məhdudiyyətidir. Volley 2013-cü ildə yaradılmışdır və müasir protokolları və Kotlin korutinlərini dəstəkləmir. Yeni layihələr üçün Google Retrofit + OkHttp istifadə etməyi tövsiyə edir. Volley yalnız legacy layihələrinə dəstək və ya minimal şəbəkə tələbləri olan sadə tətbiqlər üçün uyğundur.
Tez-tez verilən suallar
Volley yeni layihələr üçün köhnəlmişdir — Google kitabxananı 2017-ci ildən bəri yeniləməmişdir. Müasir tətbiqlər üçün Retrofit + OkHttp və ya Ktor Client istifadə edin. Volley yalnız mövcud legacy kodunu dəstəkləmək və ya minimal şəbəkə tapşırıqları olan sadə təhsil layihələrində tətbiq oluna bilər.
Müasir texnologiyaların dəstəklənməməsi: HTTP/2, Kotlin korutinləri, çoxplatformalılıq və tipləşdirilmiş serializasiya. Volley tiplər olmadan JSONObject və JSONArray istifadə edir, bu da JSON strukturunun gözləntilərə uyğun gəlməməsi zamanı runtime xətalarına səbəb olur.
ImageLoader və NetworkImageView vasitəsilə. ImageLoader şəkillərin yaddaş keşlənməsi üçün LruCache istifadə edir və View təkrar istifadə edildikdə sorğuları avtomatik ləğv edir. NetworkImageView yükləmə zamanı placeholder göstərir və onu hazır şəkil və ya xəta göstəricisi ilə əvəz edir.
Texniki olaraq bəli — Volley callback-ləri üzərində suspendCoroutine { } sarma vasitəsilə. Lakin bu üstünlük vermir, çünki Volley korutinanın ləğvi ilə ləğvi dəstəkləmir və birbaşa Dispatchers.IO ilə işləmir. Ktor Client-i korutinlər üçün native dəstək ilə istifadə etmək daha yaxşıdır.
Timeout RetryPolicy vasitəsilə konfiqurasiya edilir. Susmaya görə DefaultRetryPolicy 2.5 saniyə timeout və bir təkrar cəhd istifadə edir. Parametrləri dəyişmək: request.retryPolicy = DefaultRetryPolicy(10000, 1, 1.0f) — 10 saniyə timeout, bir cəhd.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun