이번 포스팅에서는 Foreground Service와 Bound Service에 대해 알아보겠습니다. 이 두 가지 서비스는 안드로이드 애플리케이션 개발에서 매우 중요한 역할을 하며, 각기 다른 용도로 사용됩니다. 실제 사용 예제와 함께 차이점과 사용법을 살펴보겠습니다.
Foreground Service란 무엇인가요?
Foreground Service는 사용자가 인식할 수 있도록 알림(Notification)을 표시하면서 백그라운드 작업을 수행하는 서비스입니다. 예를 들어 음악 플레이어, 피트니스 애플리케이션 등이 Foreground Service를 사용하여 백그라운드에서 계속 실행됩니다. Foreground Service는 시스템 리소스를 많이 사용하는 경우에도 시스템에 의해 쉽게 종료되지 않도록 보장됩니다.
Foreground Service를 사용하기 위해서는 서비스 시작 시 startForeground() 메서드를 호출하여 알림을 띄워야 합니다. 이 알림은 서비스가 실행 중임을 사용자에게 알려주는 역할을 합니다.
예제 - Foreground Service 구현하기
다음은 Foreground Service를 구현하여 음악을 재생하는 예제입니다.
1. AndroidManifest.xml 설정
Foreground Service를 사용하려면, AndroidManifest.xml에 서비스에 대한 정보를 추가해야 합니다. 다음과 같이 MusicForegroundService를 선언합니다.
<service android:name=".MusicForegroundService" />
2. MusicForegroundService 클래스 구현
Foreground Service는 Notification을 사용하여 사용자에게 서비스가 실행 중임을 알립니다.
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Intent
import android.media.MediaPlayer
import android.os.IBinder
import android.os.Build
import android.util.Log
class MusicForegroundService : Service() {
private lateinit var mediaPlayer: MediaPlayer
private val channelId = "MusicServiceChannel"
override fun onCreate() {
super.onCreate()
Log.d("MusicForegroundService", "Service Created")
createNotificationChannel()
// MediaPlayer 초기화
mediaPlayer = MediaPlayer.create(this, R.raw.sample_music)
mediaPlayer.isLooping = true // 반복 재생 설정
val notification = Notification.Builder(this, channelId)
.setContentTitle("Music Service")
.setContentText("Playing Music in the Background")
.setSmallIcon(R.drawable.ic_music_note)
.build()
startForeground(1, notification) // Foreground Service 시작
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d("MusicForegroundService", "Service Started")
mediaPlayer.start() // 음악 재생 시작
return START_STICKY
}
override fun onDestroy() {
super.onDestroy()
Log.d("MusicForegroundService", "Service Destroyed")
mediaPlayer.stop() // 음악 재생 중지
mediaPlayer.release() // MediaPlayer 리소스 해제
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val serviceChannel = NotificationChannel(
channelId,
"Music Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
)
val manager = getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(serviceChannel)
}
}
}
3. Service 시작 및 중지
MainActivity에서 Foreground Service를 시작하고 중지할 수 있습니다.
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val startButton: Button = findViewById(R.id.startButton)
val stopButton: Button = findViewById(R.id.stopButton)
// Foreground Service 시작 버튼 클릭 시
startButton.setOnClickListener {
val intent = Intent(this, MusicForegroundService::class.java)
startService(intent)
}
// Foreground Service 중지 버튼 클릭 시
stopButton.setOnClickListener {
val intent = Intent(this, MusicForegroundService::class.java)
stopService(intent)
}
}
}
Bound Service란 무엇인가요?
Bound Service는 애플리케이션의 다른 컴포넌트(Activity, Fragment 등)가 Service에 바인딩하여 상호작용할 수 있는 서비스입니다. Bound Service는 클라이언트-서버와 같은 관계로, 클라이언트가 서비스에 요청을 보내고 응답을 받을 수 있습니다. 주로 클라이언트와 긴밀하게 상호작용해야 하는 경우 사용됩니다.
예제 - Bound Service 구현하기
Bound Service를 구현하여 숫자를 증가시키는 간단한 예제를 만들어 보겠습니다.
1. BoundService 클래스 구현
import android.app.Service
import android.content.Intent
import android.os.Binder
import android.os.IBinder
import android.util.Log
class BoundService : Service() {
private val binder = LocalBinder()
private var number = 0
inner class LocalBinder : Binder() {
fun getService(): BoundService = this@BoundService
}
override fun onBind(intent: Intent?): IBinder {
Log.d("BoundService", "Service Bound")
return binder
}
fun getNextNumber(): Int {
number++
return number
}
}
2. Activity에서 Bound Service 사용하기
MainActivity에서 Bound Service를 바인딩하고 사용해 보겠습니다.
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.IBinder
import android.widget.Button
import android.widget.TextView
class MainActivity : AppCompatActivity() {
private var boundService: BoundService? = null
private var isBound = false
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
val binder = service as BoundService.LocalBinder
boundService = binder.getService()
isBound = true
}
override fun onServiceDisconnected(name: ComponentName?) {
isBound = false
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val bindButton: Button = findViewById(R.id.bindButton)
val unbindButton: Button = findViewById(R.id.unbindButton)
val getNextNumberButton: Button = findViewById(R.id.getNextNumberButton)
val numberTextView: TextView = findViewById(R.id.numberTextView)
bindButton.setOnClickListener {
val intent = Intent(this, BoundService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
unbindButton.setOnClickListener {
if (isBound) {
unbindService(connection)
isBound = false
}
}
getNextNumberButton.setOnClickListener {
if (isBound) {
val nextNumber = boundService?.getNextNumber()
numberTextView.text = nextNumber.toString()
}
}
}
}
결론
이번 포스팅에서는 Foreground Service와 Bound Service에 대해 알아보고, 각각의 사용 예제를 통해 구현 방법을 살펴보았습니다. Foreground Service는 사용자에게 알림을 표시하면서 중요한 작업을 백그라운드에서 수행하는 데 유용하며, Bound Service는 클라이언트 컴포넌트와 상호작용해야 하는 경우 사용됩니다.
다음 포스팅에서는 안드로이드 서비스의 심화된 사용법과 최적화 방법에 대해 알아보도록 하겠습니다.
Kotlin 기초
https://coding-by-head.tistory.com/category/kotlin
'kotlin' 카테고리의 글 목록
임베디드 소프트웨어 개발을 위한 팁과 정보를 제공하는 '소프트웨어 공장'입니다. 함께 성장하는 개발 친구가 되어드릴게요!
coding-by-head.tistory.com
'Android System & AOSP Engineering > App Layer: Implementation' 카테고리의 다른 글
| Android Content Provider 사용법 총정리 | 시스템 데이터 접근 (Contacts 예제) (0) | 2024.11.19 |
|---|---|
| Android 서비스 최적화 완벽 가이드 | JobScheduler vs WorkManager 비교 + 예제 (0) | 2024.11.18 |
| Android Service 완벽 정리 | 백그라운드 서비스 + 음악 재생 예제 (Kotlin) (0) | 2024.11.16 |
| Android 개발 필수 개념 | Activity 생명주기 한 번에 끝내기 (0) | 2024.11.15 |
| Android Intent와 Broadcast 완벽 정리 | 명시적/암시적 Intent + BroadcastReceiver 예제 (0) | 2024.11.14 |