← Назад к вопросам

Какие знаешь Services по типу запуска?

2.3 Middle🔥 191 комментариев
#Android компоненты#Жизненный цикл и навигация

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Типы Services в Android по типу запуска

Android Services отличаются способом запуска и поведением при завершении. Понимание этих различий критично для правильной разработки.

1. Started Service (startService())

Сервис запускается через startService() и продолжает работу независимо от компонента, его запустившего:

val intent = Intent(this, MyService::class.java)
startService(intent)

class MyService : Service() {
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // Выполнение работы
        return START_STICKY  // или START_NOT_STICKY, START_REDELIVER_INTENT
    }
}

Характеристики:

  • Запускается явно через startService()
  • Нет связи с вызывающим компонентом
  • Жив, пока не вызвана stopService() или stopSelf()
  • Может быть убит системой при нехватке памяти

Типы возвращаемых значений onStartCommand():

START_STICKY: Если сервис убит системой, он перезапустится с intent = null

return START_STICKY

START_NOT_STICKY: Если сервис убит, он не перезапустится

return START_NOT_STICKY

START_REDELIVER_INTENT: Если убит, перезапустится с исходным intent

return START_REDELIVER_INTENT

2. Bound Service (bindService())

Сервис привязан к компоненту через IBinder интерфейс:

val intent = Intent(this, MyBoundService::class.java)
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)

class MyBoundService : Service() {
    private val binder = LocalBinder()
    
    override fun onBind(intent: Intent?): IBinder? {
        return binder
    }
    
    inner class LocalBinder : Binder() {
        fun getService(): MyBoundService = this@MyBoundService
    }
}

private val serviceConnection = object : ServiceConnection {
    override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
        val binder = service as MyBoundService.LocalBinder
        val myService = binder.getService()
    }
    
    override fun onServiceDisconnected(name: ComponentName?) {}
}

Характеристики:

  • Привязан к компоненту через ServiceConnection
  • Выполняет RPC (Remote Procedure Call) запросы
  • Жив, пока к нему привязан хотя бы один клиент
  • Уничтожается, когда все клиенты отвязаны (unbindService())

3. Bound Service с AIDL (Inter-Process Communication)

Для обмена данными между процессами:

// IMyAidlInterface.aidl
package com.example;
interface IMyAidlInterface {
    int add(int a, int b);
}

// Реализация в Service
class MyAidlService : Service() {
    private val stub = object : IMyAidlInterface.Stub() {
        override fun add(a: Int, b: Int): Int = a + b
    }
    
    override fun onBind(intent: Intent?): IBinder? = stub
}

// Клиент
val connection = object : ServiceConnection {
    override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
        val iface = IMyAidlInterface.Stub.asInterface(service)
        val result = iface.add(5, 3)
    }
    override fun onServiceDisconnected(name: ComponentName?) {}
}

4. Foreground Service

Сервис с видимым уведомлением, высокий приоритет:

class MyForegroundService : Service() {
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val notification = NotificationCompat.Builder(this, "channel")
            .setContentTitle("Работаю")
            .setSmallIcon(R.drawable.ic_icon)
            .build()
        
        startForeground(NOTIFICATION_ID, notification)
        
        // Долгая операция
        return START_STICKY
    }
}

// AndroidManifest.xml
<service android:name=".MyForegroundService"
    android:foregroundServiceType="location" />

Когда использовать:

  • Музыка/видео плеер
  • Навигация с GPS
  • Загрузка файлов
  • Видеовызовы

5. Intent Service (DEPRECATED)

Обработка intent на фоновом потоке, затем завершение:

class MyIntentService : IntentService("MyIntentService") {
    override fun onHandleIntent(intent: Intent?) {
        // Работа на фоновом потоке
        val result = doSomeWork()
    }
}

// Запуск
val intent = Intent(this, MyIntentService::class.java)
startService(intent)  // Сервис сам завершится после onHandleIntent

Характеристики:

  • Deprecated в API 30+
  • Обрабатывает intent на отдельном потоке
  • Автоматически завершается после onHandleIntent

6. Hybrid Service (Started + Bound)

Сочетание Started и Bound типов:

class HybridService : Service() {
    private val binder = LocalBinder()
    
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // Started часть
        startBackgroundWork()
        return START_STICKY
    }
    
    override fun onBind(intent: Intent?): IBinder? {
        // Bound часть
        return binder
    }
    
    private fun startBackgroundWork() {
        Thread {
            // Непрерывная фоновая работа
        }.start()
    }
    
    inner class LocalBinder : Binder() {
        fun getService(): HybridService = this@HybridService
        fun getStatus(): String = "Working"
    }
}

Сравнение типов

ТипЗапускЖизненный циклПрименение
StartedstartService()До stopService()Фоновые задачи
BoundbindService()До unbindService()RPC, привязанные данные
ForegroundstartForeground()Видимый, высокий приоритетДолгие видимые операции
IntentServicestartService()АвтоматическийОдноразовые задачи
HybridОбеКомбинированныйСложные сценарии

Best Practices

  • Foreground Service с уведомлением для видимых операций
  • Bound Service для взаимодействия с UI
  • WorkManager вместо Started Service для фоновых задач
  • AIDL только если нужен IPC между разными приложениями
  • Избегайте долгих операций на главном потоке в onStartCommand()
Какие знаешь Services по типу запуска? | PrepBro