이번 포스팅에서는 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는 클라이언트 컴포넌트와 상호작용해야 하는 경우 사용됩니다.
다음 포스팅에서는 안드로이드 서비스의 심화된 사용법과 최적화 방법에 대해 알아보도록 하겠습니다.
'Android' 카테고리의 다른 글
Android Content Provider - 애플리케이션 간 데이터 공유 (0) | 2024.11.19 |
---|---|
Android JobScheduler, WorkManager - 서비스의 최적화(Optimize Service) (0) | 2024.11.18 |
Android - Service (0) | 2024.11.16 |
Android - Activity (0) | 2024.11.15 |
Android - 인텐트(Intent), 브로드캐스트(Broadcast) (0) | 2024.11.14 |