Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Bound Service - коммуникация между компонентами
Bound Service - это сервис, который позволяет другим компонентам (Activity, другому Service) подключиться к нему и общаться через интерфейс. Это отличается от обычного Service, который просто выполняет работу в фоне.
Два типа Service
Started Service Bound Service
┌─────────────────┐ ┌──────────────────┐
│ Фоновая работа │ │ Коммуникация │
│ Независимо │ │ Связь с Activity │
│ Работает пока │ │ Request/Response │
│ не stopService()│ │ Привязана к │
│ │ │ жизненному цику │
└─────────────────┘ └──────────────────┘
Как работает Bound Service
// 1. Создание сервиса
class MusicService : Service() {
private val binder = MusicBinder()
override fun onBind(intent: Intent?): IBinder {
return binder // возвращаем интерфейс для связи
}
// Интерфейс для коммуникации
inner class MusicBinder : Binder() {
fun getService(): MusicService = this@MusicService
}
fun play(song: String) {
Log.d("Music", "Playing: $song")
}
fun stop() {
Log.d("Music", "Stopped")
}
}
// 2. Подключение к сервису
class MainActivity : AppCompatActivity() {
private var musicService: MusicService? = null
private var isBound = false
private val connection = object : ServiceConnection {
override fun onServiceConnected(
name: ComponentName,
service: IBinder
) {
val binder = service as MusicService.MusicBinder
musicService = binder.getService()
isBound = true
Log.d("MainActivity", "Service connected")
}
override fun onServiceDisconnected(name: ComponentName) {
isBound = false
Log.d("MainActivity", "Service disconnected")
}
}
override fun onStart() {
super.onStart()
// Подключаемся к сервису
Intent(this, MusicService::class.java).also { intent ->
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
}
override fun onStop() {
super.onStop()
// Отключаемся когда Activity скрывается
if (isBound) {
unbindService(connection)
isBound = false
}
}
fun playMusic() {
musicService?.play("MySong.mp3")
}
}
Когда использовать Bound Service
1. Медиа плеер
// Сервис воспроизводит музыку
// Activity управляет playback через bound service
class MediaService : Service() {
private var mediaPlayer: MediaPlayer? = null
fun play(uri: String) {
mediaPlayer = MediaPlayer().apply {
setDataSource(uri)
prepare()
start()
}
}
fun pause() = mediaPlayer?.pause()
fun resume() = mediaPlayer?.start()
}
2. Синхронизация данных
// Activity может запросить статус синхронизации
class SyncService : Service() {
private var syncInProgress = false
fun startSync() {
syncInProgress = true
// начать синхронизацию
}
fun getSyncStatus(): Boolean = syncInProgress
}
3. Шифрование/Криптография
// Сервис для безопасных операций
class CryptoService : Service() {
fun encrypt(data: String): String {
// криптографическая операция
return encryptionHelper.encrypt(data)
}
fun decrypt(encrypted: String): String {
return encryptionHelper.decrypt(encrypted)
}
}
4. Работа с GPS
class LocationService : Service() {
private var currentLocation: Location? = null
fun getLocation(): Location? = currentLocation
fun startTracking() {
// начать отслеживание локации
}
}
AIDL - для межпроцессной коммуникации
Если нужна коммуникация между приложениями:
// В build.gradle
// Создаём файл .aidl
// IRemoteService.aidl
package com.example.myservice;
interface IRemoteService {
void doSomething();
String getData();
}
// Сервис реализует интерфейс
class RemoteService : Service() {
private val stub = object : IRemoteService.Stub() {
override fun doSomething() {
Log.d("Remote", "Something done")
}
override fun getData(): String {
return "Remote data"
}
}
override fun onBind(intent: Intent?): IBinder = stub
}
// Другое приложение может подключиться
class ClientActivity : AppCompatActivity() {
private var remoteService: IRemoteService? = null
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName, service: IBinder) {
remoteService = IRemoteService.Stub.asInterface(service)
}
override fun onServiceDisconnected(name: ComponentName) {
remoteService = null
}
}
}
Жизненный цикл Bound Service
onCreate()
↓
onBind() ← запрос от Activity
↓
(Service работает)
↓
onUnbind() ← Activity отключилась
↓
onDestroy()
Отличие от Started Service:
- Bound Service живёт столько же, сколько подключены клиенты
- Когда все клиенты отключились, сервис может быть уничтожен
- Started Service работает независимо до явного stopService()
Практический пример - Медиа плеер
// Service
class MusicPlaybackService : Service() {
private var mediaPlayer: MediaPlayer? = null
private val binder = MusicBinder()
private var currentTrack: String = ""
inner class MusicBinder : Binder() {
fun getService() = this@MusicPlaybackService
}
override fun onBind(intent: Intent?): IBinder = binder
fun play(track: String) {
currentTrack = track
mediaPlayer = MediaPlayer().apply {
setDataSource(track)
prepare()
start()
}
}
fun pause() = mediaPlayer?.pause()
fun resume() = mediaPlayer?.start()
fun stop() = mediaPlayer?.stop()
fun getCurrentTrack() = currentTrack
fun isPlaying() = mediaPlayer?.isPlaying ?: false
}
// Activity
class PlayerActivity : AppCompatActivity() {
private var musicService: MusicPlaybackService? = null
private var isBound = false
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName, service: IBinder) {
val binder = service as MusicPlaybackService.MusicBinder
musicService = binder.getService()
isBound = true
updateUI()
}
override fun onServiceDisconnected(name: ComponentName) {
isBound = false
}
}
override fun onStart() {
super.onStart()
bindService(
Intent(this, MusicPlaybackService::class.java),
connection,
Context.BIND_AUTO_CREATE
)
}
override fun onStop() {
super.onStop()
if (isBound) {
unbindService(connection)
isBound = false
}
}
fun playButtonClick() {
musicService?.play("/storage/music/song.mp3")
}
private fun updateUI() {
val track = musicService?.getCurrentTrack()
val isPlaying = musicService?.isPlaying() ?: false
// обновляем UI
}
}
Вывод
Bound Service используется когда:
- Нужна двусторонняя коммуникация между Activity и Service
- Request/Response модель - Activity запрашивает данные
- Тесная связь - Service зависит от подключённых клиентов
- Медиа плеер, GPS, сдвиг данных - типичные примеры
Отличается от Started Service тем, что:
- Привязан к жизненному циклу клиентов
- Прекращает работу когда все отключились
- Позволяет вызывать методы сервиса из Activity