Volley — je síťová knihovna pro Android vyvinutá společností Google pro efektivní provádění HTTP požadavků a načítání obrázků. Knihovna automaticky spravuje fond vláken, ukládá odpovědi do mezipaměti a priorizuje požadavky. Podle Google, 2025 zůstává Volley oblíbenou volbou pro projekty, které vyžadují rychlý start bez konfigurace složitých závislostí.
Hlavní body
Volley — je knihovna pro síťovou komunikaci v aplikacích pro Android, představená společností Google na konferenci I/O 2013. Název Volley znamená „salva“ — knihovna je určena k provádění mnoha paralelních rychlých požadavků, typických pro UI orientované aplikace, kde je důležitá rychlost odezvy rozhraní.
Volley byla vytvořena jako řešení problémů HttpURLConnection a AsyncTask: ruční správa vláken, chybějící ukládání do mezipaměti, obtížnost priorizace požadavků a rozsáhlý kód. Google umístil Volley jako knihovnu pro operace typu fire-and-forget — malé požadavky, jejichž výsledek se okamžitě zobrazí v rozhraní.
Architektura Volley zahrnuje tři hlavní komponenty: RequestQueue (správce fronty), CacheDispatcher (vlákno pro odpovědi v mezipaměti) a NetworkDispatcher (síťová vlákna). Tato architektura automaticky rozděluje požadavky: nejprve se zkontroluje mezipaměť a pouze v případě její nepřítomnosti se provede síťový požadavek. To snižuje zpoždění pro opakovaná data o 50–80%.
RequestQueue — centrální třída Volley. Přidávají se do ní objekty Request<T> a fronta je automaticky rozděluje na dva typy vláken: CacheDispatcher (jedno vlákno, zpracovává požadavky s možnou mezipamětí) a NetworkDispatcher (několik vláken, provádějí skutečné HTTP požadavky). Ve výchozím nastavení Volley vytváří 4 síťová vlákna.
Při přidání požadavku RequestQueue zkontroluje, zda může být obsloužen z mezipaměti. Pokud mezipaměť obsahuje aktuální odpověď, CacheDispatcher ji vrátí okamžitě bez síťového požadavku. Pokud je mezipaměť zastaralá nebo chybí, požadavek je předán NetworkDispatcher. Priorita požadavku (low, normal, high, immediate) určuje pořadí zpracování ve frontě — požadavky s prioritou high jsou zpracovány dříve než normal.
Po provedení požadavku je výsledek doručen do hlavního vlákna (UI thread) prostřednictvím Handler. Volley automaticky přepíná callbacky onResponse() a onErrorResponse() na hlavní vlákno, takže můžete přímo aktualizovat rozhraní v callbacku bez dalšího přepínání. To zjednodušuje kód a eliminuje celou třídu chyb souvisejících s vlákny.
Další vlastností Volley je automatická deduplikace požadavků. Pokud jsou do fronty přidány dva identické GET požadavky na stejnou URL se stejnými parametry, Volley provede pouze jeden z nich a vrátí stejnou odpověď oběma callbackům. To je užitečné zejména pro obrazovky, kde několik komponent nezávisle požaduje stejná data — například profil uživatele, který je současně potřebný pro záhlaví i fragment s nastavením.
Každý požadavek prochází sadou kroků: vytvoření Request, přidání do RequestQueue, kontrola mezipaměti (CacheDispatcher), provedení HTTP požadavku (NetworkDispatcher), parsování odpovědi pomocí Response.Listener, doručení výsledku do UI vlákna. Při zrušení požadavku (cancel) RequestQueue jej odstraní z fronty a zabrání volání callbacků.
Volley také podporuje RetryPolicy, který určuje počet opakovaných pokusů při selhání. DefaultRetryPolicy ve výchozím nastavení provádí jeden opakovaný pokus s timeoutem 2,5 sekundy. Pro nestabilní připojení lze počet pokusů zvýšit na 3 a timeout na 10 sekund. Vlastní RetryPolicy se implementuje přes rozhraní RetryPolicy s metodami getCurrentTimeout, getCurrentRetryCount a retry.
Volley poskytuje hotové typy požadavků pro běžné formáty dat. Každý typ implementuje abstraktní třídu Request<T> a definuje způsob parsování odpovědi. Pro vlastní formáty můžete vytvořit svůj typ přepsáním metody parseNetworkResponse.
| Typ požadavku | Návratový typ | Účel |
|---|---|---|
| StringRequest | String | Získání surové textové odpovědi |
| JsonObjectRequest | JSONObject | Parsování JSON objektu |
| JsonArrayRequest | JSONArray | Parsování JSON pole |
| ImageRequest | Bitmap | Načtení a dekódování obrázku |
| ClearCacheRequest | — | Vymazání mezipaměti Volley |
Pro práci s Gson nebo Kotlinx Serialization můžete vytvořit vlastní Request<T>, který v parseNetworkResponse používá zvolený parser. To umožňuje získávat typované objekty přímo, bez ručního parsování JSONObject. Tento přístup je užitečný zejména pro projekty, které již používají serializaci přes Gson nebo Moshi.
Pro odesílání dat Volley podporuje tři typy těla: JSONObject (přes JsonObjectRequest s metodou POST), Form-encoded (přes HashMap<String, String> v konstruktoru) a Multipart (přes vlastní MultipartRequest). Multipart požadavky jsou užitečné pro nahrávání obrázků a souborů, ale vyžadují ruční implementaci, protože Volley nemá vestavěnou podporu pro multipart/form-data na rozdíl od OkHttp nebo Dio.
Omezení Volley jsou patrná při práci s velkými odpověďmi. Volley načte celou odpověď do paměti před předáním callbacku, což může způsobit OutOfMemoryError pro JSON soubory větší než 10–20 MB. Pro načítání velkých souborů Volley není vhodný — použijte DownloadManager nebo OkHttp s streamovaným ResponseBody. Volley také nepodporuje obnovení přerušených stahování (Range header) a nepracuje s streamovacími protokoly jako Server-Sent Events nebo WebSocket v reálném čase.
Podívejme se na základní příklad — StringRequest pro získání dat ze serveru. Nejprve se vytvoří RequestQueue přes Volley.newRequestQueue(context). Poté se sestaví požadavek s URL a callbacky pro úspěch a chybu.
val queue = Volley.newRequestQueue(context)
val request = StringRequest(
Request.Method.GET,
"https://api.github.com/users/octocat",
{ response ->
println("Odpověď: $response")
},
{ error ->
println("Chyba: ${error.message}")
}
)
queue.add(request)
Pro JSON požadavek se používá JsonObjectRequest, který automaticky parsuje odpověď do JSONObject. Volley podporuje GET a POST požadavky. Pro POST se JSONObject předává v těle požadavku.
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("Vytvořeno: ${response.getString("id")}")
},
{ println("Chyba: $it") }
)
queue.add(request)
Pro zrušení požadavku se používá metoda cancel() nebo skupinové zrušení podle tagu. Při zrušení Volley nevolá ani onResponse ani onErrorResponse, což zabraňuje aktualizaci rozhraní po opuštění obrazovky. To je důležité pro prevenci úniků paměti v Activity a Fragment.
request.tag = "profile_request"
queue.add(request)
// Zrušit při opuštění obrazovky
queue.cancelAll("profile_request")
ImageLoader — je třída obalující RequestQueue, optimalizovaná pro načítání obrázků. Podporuje paměťovou mezipaměť (LruCache) a automaticky ruší požadavky při opětovném použití ImageView v seznamech RecyclerView. ImageLoader také škáluje obrázky na velikost View, čímž šetří paměť.
NetworkImageView — je vlastní View, které se integruje s ImageLoader a automaticky spravuje načítání: nastaví placeholder během načítání, nahradí chybou při selhání a zruší požadavek při opuštění obrazovky View. DefaultImageUrlLoader načte obrázek podle URL a uloží jej do LruCache pro rychlé opětovné zobrazení.
Pro použití ImageLoader stačí vytvořit instanci přes ImageLoader(queue, ImageCache), kde ImageCache je implementace rozhraní ImageCache s LruCache uvnitř. NetworkImageView v XML se propojí s ImageLoader přes metodu setImageUrl() a celé načítání probíhá zcela automaticky bez dalšího kódu pro zpracování placeholderů a chyb.
Vytváření RequestQueue v každé Activity — častá chyba vedoucí k duplikaci vláken a zmatku v mezipaměti. RequestQueue se doporučuje vytvářet jednou v Application nebo přes singleton třídu. V opačném případě bude mít každá obrazovka vlastní fond vláken a mezipaměť bude uložena zvlášť pro každou frontu.
Ignorování rušení požadavků při otáčení obrazovky. Při změně konfigurace je Activity znovu vytvořena a callbacky staré Activity zůstávají v paměti. To vede k únikům a pokusu o aktualizaci zničeného View. Vždy rušte požadavky v onStop() přes cancelAll() s tagem specifickým pro Activity.
Volley nepodporuje HTTP/2 a korutiny — to není chyba použití, ale architektonické omezení. Volley byl vytvořen v roce 2013 a nepodporuje moderní protokoly a Kotlin korutiny. Pro nové projekty Google doporučuje Retrofit + OkHttp. Volley je vhodný pouze pro podporu legacy projektů nebo jednoduchých aplikací s minimálními síťovými požadavky.
Často kladené otázky
Volley je pro nové projekty zastaralý — Google knihovnu neaktualizoval od roku 2017. Pro moderní aplikace použijte Retrofit + OkHttp nebo Ktor Client. Volley lze použít pouze pro podporu stávajícího legacy kódu nebo v jednoduchých vzdělávacích projektech s minimálními síťovými úkoly.
Nedostatek podpory moderních technologií: HTTP/2, Kotlin korutin, multiplatformnosti a typované serializace. Volley používá JSONObject a JSONArray bez typů, což vede k runtime chybám při nesouladu struktury JSON s očekáváním.
Přes ImageLoader a NetworkImageView. ImageLoader používá LruCache pro ukládání obrázků do paměti a automaticky ruší požadavky při opětovném použití View. NetworkImageView zobrazí placeholder během načítání a nahradí jej hotovým obrázkem nebo indikátorem chyby.
Technicky ano — přes obal suspendCoroutine { } kolem callbacků Volley. To ale nepřináší výhody, protože Volley nepodporuje zrušení zrušením korutiny a nepracuje přímo s Dispatchers.IO. Lepší je použít Ktor Client s nativní podporou korutin.
Timeout se nastavuje přes RetryPolicy. Ve výchozím nastavení DefaultRetryPolicy používá timeout 2,5 sekundy a jeden opakovaný pokus. Změna parametrů: request.retryPolicy = DefaultRetryPolicy(10000, 1, 1.0f) — 10 sekund timeout, jeden pokus.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také