Background Service — είναι ένα στοιχείο Android, σχεδιασμένο για την εκτέλεση μακροχρόνιων λειτουργιών στο παρασκήνιο χωρίς διεπαφή χρήστη. Σε αντίθεση με το Activity, το Service συνεχίζει να λειτουργεί ακόμα και όταν η εφαρμογή είναι ελαχιστοποιημένη ή ο χρήστης έχει μεταβεί σε άλλη εφαρμογή. Σύμφωνα με το Android Developers, 2026, υπάρχουν τρεις τύποι υπηρεσιών: Started Service, Bound Service και Foreground Service, ο καθένας με τον δικό του κύκλο ζωής και πεδίο εφαρμογής.
Κύρια σημεία
Background Service (ή απλά Service) — είναι ένα από τα τέσσερα βασικά στοιχεία μιας εφαρμογής Android μαζί με τα Activity, BroadcastReceiver και ContentProvider. Σε αντίθεση με το Activity, το Service δεν έχει οπτική διεπαφή και προορίζεται για την εκτέλεση λειτουργιών που πρέπει να συνεχίζονται ανεξάρτητα από το αν η εφαρμογή βρίσκεται στο προσκήνιο ή όχι.
Το Service λειτουργεί στο κύριο νήμα (main thread) της εφαρμογής, επομένως οποιεσδήποτε λειτουργίες αποκλεισμού εντός του απαιτούν τη δημιουργία ξεχωριστού νήματος. Εάν αυτό δεν γίνει, το σύστημα θα προκαλέσει ANR (Application Not Responding). Για απλές λειτουργίες παρασκηνίου, το Android παρέχει το IntentService, το οποίο δημιουργεί αυτόματα ένα νήμα εργασίας. Σε σύγχρονα έργα, συνιστάται η χρήση Kotlin-κορουτίνων με CoroutineScope εντός του Service για ασύγχρονη επεξεργασία χωρίς αποκλεισμό του κύριου νήματος.
Κύριος σκοπός του Service είναι η αναπαραγωγή μουσικής, η λήψη αρχείων, η εργασία με αιτήματα δικτύου, ο συγχρονισμός δεδομένων και άλλες εργασίες που πρέπει να συνεχίζονται μετά την αποχώρηση του χρήστη από την εφαρμογή. Ωστόσο, με την κυκλοφορία του Android 8, οι προγραμματιστές πρέπει να επιλέγουν συνειδητά μεταξύ των τύπων υπηρεσιών, λαμβάνοντας υπόψη τους περιορισμούς της εργασίας παρασκηνίου.
Service έχει τον δικό του κύκλο ζωής, ο οποίος διαφέρει από το Activity. Περιλαμβάνει τέσσερις βασικές μεθόδους: onCreate, onStartCommand, onBind και onDestroy. Η κατανόηση αυτού του κύκλου είναι απαραίτητη για τη σωστή υλοποίηση εργασιών παρασκηνίου χωρίς διαρροές μνήμης.
Η μέθοδος onCreate καλείται κατά τη δημιουργία της υπηρεσίας, μία φορά κατά τη διάρκεια της ζωής της. Σε αυτήν αρχικοποιούνται πόροι: χρονοδιακόπτες, συνδέσεις βάσης δεδομένων, υποδοχές. Η μέθοδος onStartCommand καλείται κάθε φορά που καλείται το startService, επιτρέποντας την αποστολή εντολών σε μια ήδη εκτελούμενη υπηρεσία. Η επιστρεφόμενη τιμή καθορίζει τη συμπεριφορά του συστήματος κατά την επανεκκίνηση.
class DownloadService : Service() {
override fun onCreate() {
super.onCreate()
initializeDownloader()
}
override fun onStartCommand(
intent: Intent?,
flags: Int,
startId: Int
): Int {
downloadFile(intent?.getStringExtra("url"))
return START_STICKY
}
override fun onBind(intent: Intent): IBinder? = null
}
onBind καλείται κατά τη σύνδεση της υπηρεσίας μέσω bindService και επιστρέφει ένα αντικείμενο IBinder για αλληλεπίδραση με τον πελάτη. Αυτή η μέθοδος χρησιμοποιείται μόνο για Bound Service. onDestroy — η τελευταία κλήση πριν από την καταστροφή της υπηρεσίας. Σε αυτήν απελευθερώνονται όλοι οι πόροι, τα νήματα που σταματήθηκαν και οι εργασίες που ακυρώθηκαν.
Android προσφέρει τρεις τύπους Service, ο καθένας σχεδιασμένος για το δικό του σενάριο. Η επιλογή λανθασμένου τύπου μπορεί να οδηγήσει σε ασταθή λειτουργία της εφαρμογής ή κατανάλωση μπαταρίας.
Started Service ξεκινά με την κλήση startService και λειτουργεί μέχρι να καλέσει stopSelf ή stopService. Είναι κατάλληλο για εργασίες που πρέπει να εκτελεστούν άμεσα: αποστολή αναλυτικών στοιχείων, επεξεργασία εικόνας, λήψη ενός αρχείου. Μετά την ολοκλήρωση της εργασίας, η υπηρεσία σταματά αυτόματα.
Bound Service παρέχει μια διεπαφή πελάτη-εξυπηρετητή, επιτρέποντας σε Activity, Fragment ή άλλο στοιχείο να αλληλεπιδρά με την υπηρεσία. Η υπηρεσία ζει όσο υπάρχει τουλάχιστον ένας συνδεδεμένος πελάτης. Όταν όλοι οι πελάτες αποσυνδεθούν, η υπηρεσία καταστρέφεται. Το Bound Service είναι βολικό για εργασίες που απαιτούν αμφίδρομη επικοινωνία: πρόγραμμα αναπαραγωγής μουσικής, πλοήγηση.
Foreground Service — είναι ένα Started Service με μόνιμη ειδοποίηση στη γραμμή κατάστασης. Το σύστημα θεωρεί αυτήν την υπηρεσία ενεργή και δεν τη σκοτώνει ακόμα και όταν η μνήμη είναι ανεπαρκής. Το Foreground Service είναι υποχρεωτικό για αναπαραγωγή μουσικής, εγγραφή ήχου, παρακολούθηση τοποθεσίας και άλλες εργασίες σημαντικές για τον χρήστη.
| Παράμετρος | Started | Bound | Foreground |
|---|---|---|---|
| Εκκίνηση | startService | bindService | startForeground |
| Διάρκεια ζωής | μέχρι stopSelf | όσο υπάρχουν πελάτες | μέχρι stopForeground |
| Ειδοποίηση | όχι | όχι | υποχρεωτικά |
| Τερματίζεται | ναι | ναι | όχι |
| Παράδειγμα | λήψη | πρόγραμμα αναπαραγωγής | μουσική |
Η δημιουργία μιας υπηρεσίας ξεκινά με τη δήλωση μιας κλάσης που κληρονομεί από το Service και την καταχώρησή της στο AndroidManifest.xml. Χωρίς καταχώρηση στο manifest, το σύστημα δεν μπορεί να ξεκινήσει την υπηρεσία και οποιαδήποτε κλήση startService θα οδηγήσει σε εξαίρεση.
// Καταχώρηση στο AndroidManifest.xml
@SuppressLint("ForegroundServiceType")
class SyncService : Service() {
override fun onStartCommand(
intent: Intent?,
flags: Int,
startId: Int
): Int {
startForeground(
NOTIFICATION_ID,
createNotification()
)
performSync(intent)
return START_NOT_STICKY
}
}
Για την εκκίνηση μιας υπηρεσίας από Activity ή Fragment χρησιμοποιείται Intent με ρητή αναφορά της κλάσης της υπηρεσίας. Από το Android 8, για Foreground Service απαιτείται υποχρεωτικά η άδεια FOREGROUND_SERVICE στο manifest.
// Εκκίνηση Started Service
val intent = Intent(this, SyncService::class.java)
intent.putExtra("action", "sync")
startService(intent)
// Εκκίνηση Foreground Service (Android 8+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent)
} else {
startService(intent)
}
Από το Android 8 (API 26) η Google εισήγαγε αυστηρούς περιορισμούς στις υπηρεσίες παρασκηνίου. Η εκκίνηση Service στο παρασκήνιο (όταν η εφαρμογή δεν βρίσκεται στο προσκήνιο) επιτρέπεται μόνο σε εξαιρετικές περιπτώσεις: κατά τη λήψη push-ειδοποίησης, μετά την εκκίνηση της συσκευής ή μέσω JobScheduler.
Για μακροχρόνιες εργασίες που δεν απαιτούν άμεση εκτέλεση, συνιστάται η χρήση WorkManager ή JobScheduler. Εάν η εφαρμογή χρειάζεται πραγματικά μια εκτελούμενη υπηρεσία, ο μόνος τρόπος είναι το Foreground Service με ειδοποίηση που βλέπει ο χρήστης. Η εκκίνηση υπηρεσίας χωρίς ειδοποίηση στο παρασκήνιο θα αγνοηθεί από το σύστημα.
JobIntentService — είναι μια εξειδικευμένη κλάση που εμφανίστηκε στη support library για λειτουργία σε Android 5+. Συνδυάζει τη συμπεριφορά του IntentService (αυτόματο νήμα εργασίας, σειριακή επεξεργασία) με προγραμματισμό μέσω JobScheduler. Σε Android 8+, το JobIntentService χρησιμοποιεί το JobScheduler εσωτερικά, ενώ σε παλαιότερες εκδόσεις — ένα κανονικό Service. Αυτό επιτρέπει την ομοιόμορφη επεξεργασία εργασιών παρασκηνίου χωρίς πρόσθετους ελέγχους έκδοσης Android.
class UploadJobService : JobIntentService() {
companion object {
private const val JOB_ID = 1000
fun enqueueWork(context: Context, work: Intent) {
enqueueWork(
context,
UploadJobService::class.java,
JOB_ID,
work
)
}
}
override fun onHandleWork(intent: Intent) {
val fileUri = intent.getStringExtra("file_uri")
// Εκτελείται σε νήμα παρασκηνίου
uploadFile(fileUri)
}
}
Ένα από τα συχνά προβλήματα κατά την εργασία με Background Service είναι οι διαρροές μνήμης. Καθώς το Service μπορεί να ζει περισσότερο από το Activity, οι αναφορές στο Activity εντός του Service (μέσω listener, callback ή broadcast) οδηγούν στην αδυναμία συλλογής απορριμμάτων για τα στοιχεία UI. Συνιστάται η χρήση WeakReference, ViewModel ή LiveData για τη σύνδεση του Service με το UI. Στο onDestroy, πρέπει υποχρεωτικά να ακυρώνονται όλες οι συνδρομές, να σταματούν τα νήματα και να κλείνουν οι δρομείς.
Η επιλογή μεταξύ Background Service και WorkManager εξαρτάται από το σενάριο. Το Service είναι κατάλληλο για εργασίες που πρέπει να εκτελούνται άμεσα και συνεχόμενα: αναπαραγωγή μουσικής, εγγραφή ήχου, παρακολούθηση GPS. Το WorkManager είναι καλύτερο για αναβαλλόμενες, εγγυημένες εργασίες: συγχρονισμός, αποστολή αναλυτικών στοιχείων, λήψη αρχείων καταγραφής. Το WorkManager επιβιώνει από επανεκκίνηση της συσκευής, ενώ το Service όχι. Το Service μπορεί να είναι Foreground με ειδοποίηση, ενώ το WorkManager λειτουργεί σιωπηλά στο παρασκήνιο. Στην πράξη, οι προγραμματιστές συνδυάζουν και τις δύο προσεγγίσεις: Foreground Service για κρίσιμες εργασίες χρήστη και WorkManager για συντήρηση παρασκηνίου.
Το Android 12 εισήγαγε τη σημαία android:foregroundServiceType, η οποία απαιτεί τον καθορισμό του τύπου υπηρεσίας: dataSync, camera, connectedDevice, location, mediaPlayback και άλλα. Η λανθασμένη αναφορά τύπου οδηγεί σε εξαίρεση κατά την εκκίνηση. Αυτή η πρακτική καθιστά το Background Service πιο διαφανές για τον χρήστη και το σύστημα.
Η σωστή καταχώρηση Service στο manifest περιλαμβάνει τα χαρακτηριστικά exported (προσβασιμότητα για εξωτερικές εφαρμογές), foregroundServiceType (τύπος υπηρεσίας παρασκηνίου σε Android 12+) και permission. Για Bound Service, πρέπει επίσης να δηλωθεί android:permission="android.permission.BIND_JOB_SERVICE" για JobIntentService. Χωρίς καταχώρηση στο manifest, οποιαδήποτε κλήση startService ή bindService θα οδηγήσει σε εξαίρεση, επομένως ο έλεγχος του manifest είναι το πρώτο βήμα κατά τη διάγνωση προβλημάτων με το Service.
Συχνές ερωτήσεις
Service εκτελείται στο κύριο νήμα (UI Thread) της εφαρμογής. Οποιαδήποτε λειτουργία αποκλεισμού εντός του onStartCommand ή onHandleIntent πρέπει να μεταφερθεί σε ξεχωριστό νήμα ή κορουτίνα, διαφορετικά το σύστημα θα προκαλέσει ANR μέσα σε 5 δευτερόλεπτα.
IntentService — είναι μια υποκλάση του Service που δημιουργεί αυτόματα ένα νήμα εργασίας και επεξεργάζεται εντολές διαδοχικά. Μετά την ολοκλήρωση της τελευταίας εργασίας, το IntentService σταματά αυτόματα. Από το Android 8, το IntentService θεωρείται παρωχημένο υπέρ του JobIntentService ή WorkManager.
Η εκκίνηση Started Service από το παρασκήνιο σε Android 12 απαγορεύεται. Εξαίρεση αποτελεί το Foreground Service με δηλωμένο foregroundServiceType στο manifest και έγκυρη ειδοποίηση. Επίσης, επιτρέπεται μια σύντομη εκκίνηση μετά από λήψη μηνύματος FCM υψηλής προτεραιότητας.
Υπάρχουν τρεις τρόποι: BroadcastReceiver με τοπική εκπομπή, ο μηχανισμός Messenger μέσω Handler, και LiveData/Flow στην αρχιτεκτονική MVVM με κοινό ViewModel. Για Bound Service, χρησιμοποιείται IBinder με άμεση κλήση μεθόδων.
Εάν το Service είχε ξεκινήσει με τη σημαία START_STICKY, το σύστημα θα το επανεκκινήσει μετά την καταστροφή της διεργασίας λόγω ανεπαρκούς μνήμης. Η σημαία START_NOT_STICKY σημαίνει ότι το σύστημα δεν θα επανεκκινήσει την υπηρεσία. Το START_REDELIVER_INTENT είναι παρόμοιο με το START_STICKY, αλλά μεταδίδει το τελευταίο Intent.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης