Volley — είναι μια βιβλιοθήκη δικτύου για Android, που αναπτύχθηκε από την Google για αποτελεσματική εκτέλεση αιτημάτων HTTP και φόρτωση εικόνων. Η βιβλιοθήκη διαχειρίζεται αυτόματα το pool νημάτων, αποθηκεύει προσωρινά τις απαντήσεις και δίνει προτεραιότητα στα αιτήματα. Σύμφωνα με το Google, 2025, το Volley παραμένει δημοφιλής επιλογή για έργα που απαιτούν γρήγορη εκκίνηση χωρίς ρύθμιση πολύπλοκων εξαρτήσεων.
Κύρια σημεία
Volley — είναι μια βιβλιοθήκη για δικτυακή επικοινωνία σε εφαρμογές Android, που παρουσιάστηκε από την Google στο συνέδριο I/O 2013. Το όνομα Volley σημαίνει “ριπή” — η βιβλιοθήκη σχεδιάστηκε για την εκτέλεση πολλαπλών παράλληλων γρήγορων αιτημάτων, χαρακτηριστικών για εφαρμογές προσανατολισμένες στο UI, όπου η ταχύτητα απόκρισης της διεπαφής είναι σημαντική.
Το Volley δημιουργήθηκε ως λύση στα προβλήματα των HttpURLConnection και AsyncTask: χειροκίνητη διαχείριση νημάτων, έλλειψη προσωρινής αποθήκευσης, δυσκολία ιεράρχησης αιτημάτων και ογκώδης κώδικας. Η Google τοποθέτησε το Volley ως βιβλιοθήκη για λειτουργίες τύπου fire-and-forget — μικρά αιτήματα των οποίων το αποτέλεσμα εμφανίζεται αμέσως στη διεπαφή.
Η αρχιτεκτονική του Volley περιλαμβάνει τρία κύρια στοιχεία: RequestQueue (διαχειριστής ουράς), CacheDispatcher (νήμα για προσωρινά αποθηκευμένες απαντήσεις) και NetworkDispatcher (νήματα δικτύου). Αυτή η αρχιτεκτονική κατανέμει αυτόματα τα αιτήματα: πρώτα ελέγχεται η cache και μόνο αν δεν υπάρχει εκτελείται το αίτημα δικτύου. Αυτό μειώνει την καθυστέρηση για επαναλαμβανόμενα δεδομένα κατά 50–80%.
RequestQueue — η κεντρική κλάση του Volley. Σε αυτήν προστίθενται αντικείμενα Request<T> και η ουρά τα κατανέμει αυτόματα σε δύο τύπους νημάτων: CacheDispatcher (ένα νήμα, επεξεργάζεται αιτήματα με πιθανή cache) και NetworkDispatcher (πολλαπλά νήματα, εκτελούν πραγματικά αιτήματα HTTP). Από προεπιλογή, το Volley δημιουργεί 4 νήματα δικτύου.
Κατά την προσθήκη ενός αιτήματος, το RequestQueue ελέγχει αν μπορεί να εξυπηρετηθεί από την cache. Αν η cache περιέχει μια ενημερωμένη απάντηση, το CacheDispatcher την επιστρέφει αμέσως, χωρίς αίτημα δικτύου. Αν η cache είναι ξεπερασμένη ή απουσιάζει, το αίτημα μεταβιβάζεται στο NetworkDispatcher. Η προτεραιότητα του αιτήματος (low, normal, high, immediate) καθορίζει τη σειρά επεξεργασίας εντός της ουράς — τα αιτήματα με προτεραιότητα high επεξεργάζονται πριν από τα normal.
Μετά την εκτέλεση του αιτήματος, το αποτέλεσμα παραδίδεται στο κύριο νήμα (UI thread) μέσω του Handler. Το Volley αλλάζει αυτόματα τα callbacks onResponse() και onErrorResponse() στο κύριο νήμα, έτσι μπορείτε να ενημερώνετε απευθείας τη διεπαφή στο callback χωρίς πρόσθετες εναλλαγές. Αυτό απλοποιεί τον κώδικα και εξαλείφει μια ολόκληρη κατηγορία σφαλμάτων που σχετίζονται με νήματα.
Ένα άλλο χαρακτηριστικό του Volley είναι η αυτόματη αφαίρεση διπλότυπων αιτημάτων. Αν δύο πανομοιότυπα αιτήματα GET προς την ίδια διεύθυνση URL με τις ίδιες παραμέτρους προστεθούν στην ουρά, το Volley εκτελεί μόνο ένα από αυτά και επιστρέφει την ίδια απάντηση και στα δύο callbacks. Αυτό είναι ιδιαίτερα χρήσιμο για οθόνες όπου πολλά στοιχεία ζητούν ανεξάρτητα τα ίδια δεδομένα — για παράδειγμα, το προφίλ χρήστη που χρειάζεται ταυτόχρονα τόσο η κεφαλίδα όσο και το τμήμα με ρυθμίσεις.
Κάθε αίτημα περνά από μια σειρά βημάτων: δημιουργία Request, προσθήκη στο RequestQueue, έλεγχος cache (CacheDispatcher), εκτέλεση αιτήματος HTTP (NetworkDispatcher), ανάλυση απόκρισης μέσω Response.Listener, παράδοση αποτελέσματος στο νήμα UI. Κατά την ακύρωση του αιτήματος (cancel), το RequestQueue το αφαιρεί από την ουρά και αποτρέπει την κλήση των callbacks.
Το 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 | — | Εκκαθάριση cache 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 φορτώνει ολόκληρη την απόκριση στη μνήμη πριν τη μεταβιβάσει στο callback, το οποίο μπορεί να προκαλέσει OutOfMemoryError για αρχεία JSON μεγαλύτερα από 10–20 MB. Για φόρτωση μεγάλων αρχείων, το Volley δεν είναι κατάλληλο — χρησιμοποιήστε το DownloadManager ή το OkHttp με streaming ResponseBody. Το Volley επίσης δεν υποστηρίζει συνέχιση διακοπτόμενων λήψεων (Range header) και δεν λειτουργεί με πρωτόκολλα ροής όπως Server-Sent Events ή WebSocket σε πραγματικό χρόνο.
Ας δούμε ένα βασικό παράδειγμα — StringRequest για λήψη δεδομένων από τον διακομιστή. Πρώτα δημιουργείται το RequestQueue μέσω Volley.newRequestQueue(context). Στη συνέχεια, το αίτημα με URL και callbacks για επιτυχία και σφάλμα συντίθεται.
val queue = Volley.newRequestQueue(context)
val request = StringRequest(
Request.Method.GET,
"https://api.github.com/users/octocat",
{ response ->
println("Απόκριση: $response")
},
{ error ->
println("Σφάλμα: ${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("Δημιουργήθηκε: ${response.getString("id")}")
},
{ println("Σφάλμα: $it") }
)
queue.add(request)
Για ακύρωση αιτήματος χρησιμοποιείται η μέθοδος cancel() ή ομαδική ακύρωση βάσει ετικέτας. Κατά την ακύρωση, το Volley δεν καλεί ούτε το onResponse ούτε το onErrorResponse, αποτρέποντας την ενημέρωση της διεπαφής μετά την αποχώρηση από την οθόνη. Αυτό είναι σημαντικό για την αποφυγή διαρροών μνήμης σε Activity και Fragment.
request.tag = "profile_request"
queue.add(request)
// Ακύρωση κατά την αποχώρηση από την οθόνη
queue.cancelAll("profile_request")
ImageLoader — είναι μια κλάση wrapper πάνω από το RequestQueue, βελτιστοποιημένη για φόρτωση εικόνων. Υποστηρίζει cache μνήμης (LruCache) και ακυρώνει αυτόματα αιτήματα κατά την επαναχρησιμοποίηση ImageView σε λίστες RecyclerView. Το ImageLoader επίσης κλιμακώνει εικόνες στο μέγεθος του View, εξοικονομώντας μνήμη.
NetworkImageView — είναι ένα προσαρμοσμένο View που ενσωματώνεται με το ImageLoader και διαχειρίζεται αυτόματα τη φόρτωση: ορίζει ένα placeholder κατά τη φόρτωση, το αντικαθιστά με σφάλμα σε αποτυχία και ακυρώνει το αίτημα όταν το View εγκαταλείπει την οθόνη. Το DefaultImageUrlLoader φορτώνει την εικόνα μέσω URL και την αποθηκεύει στο LruCache για γρήγορη επαναπροβολή.
Για χρήση του ImageLoader αρκεί να δημιουργήσετε μια παρουσία μέσω ImageLoader(queue, ImageCache), όπου ImageCache είναι η υλοποίηση της διεπαφής ImageCache με LruCache εσωτερικά. Το NetworkImageView σε XML συνδέεται με το ImageLoader μέσω της μεθόδου setImageUrl(), και ολόκληρη η φόρτωση γίνεται εντελώς αυτόματα χωρίς πρόσθετο κώδικα για χειρισμό placeholders και σφαλμάτων.
Δημιουργία RequestQueue σε κάθε Activity — ένα συνηθισμένο λάθος που οδηγεί σε διπλασιασμό νημάτων και σύγχυση στην cache. Το RequestQueue συνιστάται να δημιουργείται μία φορά στο Application ή μέσω μιας κλάσης singleton. Διαφορετικά, κάθε οθόνη θα έχει το δικό της pool νημάτων και η cache θα αποθηκεύεται ξεχωριστά για κάθε ουρά.
Παράβλεψη ακύρωσης αιτημάτων κατά την περιστροφή οθόνης. Κατά την αλλαγή διαμόρφωσης, το Activity αναδημιουργείται και τα callbacks του παλιού Activity παραμένουν στη μνήμη. Αυτό οδηγεί σε διαρροές και προσπάθεια ενημέρωσης ενός κατεστραμμένου View. Να ακυρώνετε πάντα τα αιτήματα στο onStop() μέσω cancelAll() με μια ετικέτα συγκεκριμένη για το Activity.
Το Volley δεν υποστηρίζει HTTP/2 και coroutines — αυτό δεν είναι σφάλμα χρήσης, αλλά αρχιτεκτονικός περιορισμός. Το Volley δημιουργήθηκε το 2013 και δεν υποστηρίζει σύγχρονα πρωτόκολλα και Kotlin coroutines. Για νέα έργα, η Google συνιστά τη χρήση Retrofit + OkHttp. Το Volley είναι κατάλληλο μόνο για υποστήριξη παλαιών έργων ή απλών εφαρμογών με ελάχιστες απαιτήσεις δικτύου.
Συχνές ερωτήσεις
Volley είναι ξεπερασμένο για νέα έργα — η Google δεν έχει ενημερώσει τη βιβλιοθήκη από το 2017. Για σύγχρονες εφαρμογές χρησιμοποιήστε Retrofit + OkHttp ή Ktor Client. Το Volley μπορεί να εφαρμοστεί μόνο για υποστήριξη υπάρχοντος παλαιού κώδικα ή σε απλά εκπαιδευτικά έργα με ελάχιστες δικτυακές εργασίες.
Έλλειψη υποστήριξης σύγχρονων τεχνολογιών: HTTP/2, Kotlin coroutines, πολλαπλών πλατφορμών και τυποποιημένης σειριοποίησης. Το Volley χρησιμοποιεί JSONObject και JSONArray χωρίς τύπους, οδηγώντας σε σφάλματα χρόνου εκτέλεσης όταν η δομή JSON δεν αντιστοιχεί στις προσδοκίες.
Μέσω ImageLoader και NetworkImageView. Το ImageLoader χρησιμοποιεί LruCache για προσωρινή αποθήκευση εικόνων στη μνήμη και ακυρώνει αυτόματα αιτήματα κατά την επαναχρησιμοποίηση του View. Το NetworkImageView εμφανίζει ένα placeholder κατά τη φόρτωση και το αντικαθιστά με την έτοιμη εικόνα ή έναν δείκτη σφάλματος.
Τεχνικά ναι — μέσω ενός wrapper suspendCoroutine { } γύρω από τα callbacks του Volley. Αλλά αυτό δεν παρέχει πλεονεκτήματα, καθώς το Volley δεν υποστηρίζει ακύρωση μέσω ακύρωσης του coroutine και δεν λειτουργεί άμεσα με Dispatchers.IO. Καλύτερα χρησιμοποιήστε το Ktor Client με εγγενή υποστήριξη coroutines.
Το χρονικό όριο ρυθμίζεται μέσω RetryPolicy. Από προεπιλογή, το DefaultRetryPolicy χρησιμοποιεί χρονικό όριο 2,5 δευτερολέπτων και μία επανάληψη. Αλλαγή παραμέτρων: request.retryPolicy = DefaultRetryPolicy(10000, 1, 1.0f) — 10 δευτερόλεπτα χρονικό όριο, μία προσπάθεια.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης