Volley — это сетевая библиотека для Android, разработанная компанией Google для эффективного выполнения HTTP-запросов и загрузки изображений. Библиотека автоматически управляет пулом потоков, кэширует ответы и приоритизирует запросы. По данным Google, 2025, Volley остаётся популярным выбором для проектов, где требуется быстрое начало без настройки сложных зависимостей.
Главное
Volley — это библиотека для сетевого взаимодействия в Android-приложениях, представленная Google на конференции I/O 2013. Название Volley означает «залп» — библиотека предназначена для выполнения множества параллельных быстрых запросов, характерных для UI-ориентированных приложений, где важна скорость отклика интерфейса.
Volley была создана как решение проблем HttpURLConnection и AsyncTask: ручное управление потоками, отсутствие кэширования, сложность приоритизации запросов и громоздкий код. Google позиционировала Volley как библиотеку для операций типа «fire-and-forget» — небольших запросов, результат которых сразу отображается в интерфейсе.
Архитектура Volley включает три основных компонента: RequestQueue (менеджер очереди), CacheDispatcher (поток для кэшированных ответов) и NetworkDispatcher (сетевые потоки). Такая архитектура автоматически распределяет запросы: сначала проверяется кэш, и только при его отсутствии выполняется сетевой запрос. Это сокращает задержку для повторяющихся данных на 50–80%.
RequestQueue — центральный класс Volley. В него добавляются объекты Request<T>, и очередь автоматически распределяет их по двум типам потоков: CacheDispatcher (один поток, обрабатывает запросы с возможным кэшем) и NetworkDispatcher (несколько потоков, выполняют реальные HTTP-запросы). По умолчанию Volley создаёт 4 сетевых потока.
При добавлении запроса RequestQueue проверяет, можно ли его обслужить из кэша. Если кэш содержит актуальный ответ, CacheDispatcher возвращает его немедленно, без сетевого запроса. Если кэш устарел или отсутствует, запрос передаётся в NetworkDispatcher. Приоритет запроса (low, normal, high, immediate) определяет порядок обработки внутри очереди — запросы с high приоритетом обрабатываются раньше normal.
После выполнения запроса результат доставляется в основной поток (UI thread) через Handler. Volley автоматически переключает колбэки onResponse() и onErrorResponse() на главный поток, поэтому напрямую обновлять интерфейс можно прямо в колбэке без дополнительных переключений. Это упрощает код и устраняет целый класс ошибок с потоками.
Ещё одна особенность Volley — автоматическая дедупликация запросов. Если в очередь добавлены два одинаковых GET-запроса к одному URL с одинаковыми параметрами, Volley выполняет только один из них и возвращает одинаковый ответ обоим колбэкам. Это особенно полезно для экранов, где несколько компонентов независимо запрашивают одни и те же данные — например, профиль пользователя, который одновременно нужен и заголовку, и фрагменту с настройками.
Каждый запрос проходит через последовательность шагов: создание Request, добавление в RequestQueue, проверка кэша (CacheDispatcher), выполнение HTTP-запроса (NetworkDispatcher), парсинг ответа через Response.Listener, доставка результата в UI-поток. При отмене запроса (cancel) RequestQueue удаляет его из очереди и предотвращает вызов колбэков.
Volley также поддерживает RetryPolicy, который определяет количество повторных попыток при сбоях. DefaultRetryPolicy по умолчанию делает одну повторную попытку с таймаутом 2.5 секунды. Для нестабильных соединений количество повторов можно увеличить до 3, а таймаут — до 10 секунд. Кастомный RetryPolicy реализуется через интерфейс RetryPolicy с методами getCurrentTimeout, getCurrentRetryCount и retry.
Volley предоставляет готовые типы запросов для распространённых форматов данных. Каждый тип реализует абстрактный класс Request<T> и определяет способ парсинга ответа. Для кастомных форматов можно создать свой тип, переопределив метод parseNetworkResponse.
| Тип запроса | Возвращаемый тип | Назначение |
|---|---|---|
| StringRequest | String | Получение сырого текстового ответа |
| JsonObjectRequest | JSONObject | Парсинг JSON-объекта |
| JsonArrayRequest | JSONArray | Парсинг JSON-массива |
| ImageRequest | Bitmap | Загрузка и декодирование изображения |
| ClearCacheRequest | — | Очистка кэша Volley |
Для работы с Gson или Kotlinx Serialization можно создать кастомный Request<T>, который в parseNetworkResponse использует выбранный парсер. Это позволяет получать типизированные объекты напрямую, минуя ручной парсинг JSONObject. Такой подход особенно полезен для проектов, уже использующих сериализацию через Gson или Moshi.
Для отправки данных Volley поддерживает три типа тела: JSONObject (через JsonObjectRequest с методом POST), Form-encoded (через HashMap<String, String> в конструкторе) и Multipart (через кастомный MultipartRequest). Multipart-запросы полезны для загрузки изображений и файлов, но требуют ручной реализации, так как Volley не имеет встроенной поддержки multipart/form-data в отличие от OkHttp или Dio.
Ограничения Volley становятся заметны при работе с большими ответами. Volley загружает весь ответ в память перед передачей в колбэк, что может вызвать OutOfMemoryError для JSON-файлов размером более 10–20 МБ. Для загрузки больших файлов Volley не подходит — используйте DownloadManager или OkHttp с потоковым ResponseBody. Volley также не поддерживает докачку прерванных загрузок (Range header) и не работает с потоковыми протоколами вроде Server-Sent Events или WebSocket в реальном времени.
Рассмотрим базовый пример — StringRequest для получения данных с сервера. Сначала создаётся RequestQueue через Volley.newRequestQueue(context). Затем формируется запрос с URL и колбэками на успех и ошибку.
val queue = Volley.newRequestQueue(context)
val request = StringRequest(
Request.Method.GET,
"https://api.github.com/users/octocat",
{ response ->
println("Response: $response")
},
{ error ->
println("Error: ${error.message}")
}
)
queue.add(request)
Для JSON-запроса используется JsonObjectRequest, который автоматически парсит ответ в JSONObject. Volley поддерживает GET и POST запросы. Для POST передаётся JSONObject в теле запроса.
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("Created: ${response.getString("id")}")
},
{ println("Error: $it") }
)
queue.add(request)
Для отмены запроса используется метод cancel() или групповая отмена по тегу. При отмене Volley не вызывает ни onResponse, ни onErrorResponse, что предотвращает обновление интерфейса после ухода с экрана. Это важно для предотвращения утечек памяти в Activity и Fragment.
request.tag = "profile_request"
queue.add(request)
// Отмена при уходе с экрана
queue.cancelAll("profile_request")
ImageLoader — это класс-обёртка над RequestQueue, оптимизированный для загрузки изображений. Он поддерживает memory-кэш (LruCache) и автоматически отменяет запросы при переиспользовании ImageView в списках RecyclerView. ImageLoader также масштабирует изображения под размер View, экономя память.
NetworkImageView — это кастомный View, который интегрируется с ImageLoader и автоматически управляет загрузкой: устанавливает placeholder при загрузке, заменяет на ошибку при сбое и отменяет запрос при уходе View из экрана. DefaultImageUrlLoader загружает изображение по URL и сохраняет его в LruCache для быстрого повторного отображения.
Для использования ImageLoader достаточно создать экземпляр через ImageLoader(queue, ImageCache), где ImageCache — реализация интерфейса ImageCache с LruCache внутри. NetworkImageView в XML-разметке связывается с ImageLoader через метод setImageUrl(), и вся загрузка происходит полностью автоматически без дополнительного кода для обработки placeholder и ошибок.
Создание RequestQueue в каждом Activity — частая ошибка, приводящая к дублированию потоков и путанице в кэше. RequestQueue рекомендуется создавать один раз в Application или через синглтон-класс. В противном случае каждый экран будет иметь свой пул потоков, а кэш будет храниться отдельно для каждой очереди.
Игнорирование отмены запросов при повороте экрана. При изменении конфигурации Activity пересоздаётся, и колбэки старой Activity продолжают висеть в памяти. Это приводит к утечке и к попытке обновить уничтоженный View. Всегда отменяйте запросы в onStop() через cancelAll() по тегу, специфичному для Activity.
Volley не поддерживает HTTP/2 и корутины — это не ошибка использования, а архитектурное ограничение. Volley был создан в 2013 году и не поддерживает современные протоколы и Kotlin-корутины. Для новых проектов Google рекомендует использовать Retrofit + OkHttp. Volley подходит только для поддержки легаси-проектов или простых приложений с минимальными сетевыми требованиями.
Часто задаваемые вопросы
Volley устарел для новых проектов — Google не обновлял библиотеку с 2017 года. Для современных приложений используйте Retrofit + OkHttp или Ktor Client. Volley может применяться только для поддержки существующего легаси-кода или в простых учебных проектах с минимальными сетевыми задачами.
Отсутствие поддержки современных технологий: HTTP/2, Kotlin-корутин, мультиплатформенности и типизированной сериализации. Volley использует JSONObject и JSONArray без типов, что приводит к ошибкам runtime при несоответствии структуры JSON ожиданиям.
Через ImageLoader и NetworkImageView. ImageLoader использует LruCache для memory-кэширования изображений и автоматически отменяет запросы при переиспользовании View. NetworkImageView показывает placeholder во время загрузки и заменяет его на готовое изображение или индикатор ошибки.
Технически да — через обёртку suspendCoroutine { } над колбэками Volley. Но это не даёт преимуществ, так как Volley не поддерживает отмену по отмене корутины и не работает с Dispatchers.IO напрямую. Лучше использовать Ktor Client с нативной поддержкой корутин.
Таймаут настраивается через RetryPolicy. По умолчанию DefaultRetryPolicy использует таймаут 2.5 секунды и одну повторную попытку. Изменить параметры: request.retryPolicy = DefaultRetryPolicy(10000, 1, 1.0f) — 10 секунд таймаута, одна попытка.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также