이 글에서는 Kotlin을 사용하여 Android 앱의 서비스(Service)를 항상 백그라운드에서 실행되도록 만드는 방법을 단계별로 알아봅니다. 백그라운드 서비스는 사용자가 화면을 보고 있지 않거나 앱을 종료한 후에도 음악 재생, 위치 추적, 데이터 동기화 등의 작업을 계속 수행해야 할 때 유용합니다.
1단계 — 새 프로젝트 생성
Android Studio에서 File → New Project를 선택하고, 필요한 모든 정보를 입력하여 새 프로젝트를 생성합니다. 언어는 Kotlin으로 설정합니다.
2단계 — 레이아웃 작성 (res/layout/activity_main.xml)
아래 코드를 activity_main.xml에 추가합니다. 화면 중앙에 배치된 버튼 하나로 구성되어 있으며, 이 버튼을 누르면 백그라운드 서비스가 시작됩니다.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:text="Tutorials Point"
android:textAlignment="center"
android:textColor="@android:color/holo_green_dark"
android:textSize="32sp"
android:textStyle="bold" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="클릭하여 백그라운드 서비스 시작"
android:textSize="16sp"
android:textStyle="bold" />
</RelativeLayout>3단계 — 서비스 클래스 생성 (MyService.kt)
새 Kotlin 클래스 파일 MyService.kt를 만들고 아래 코드를 추가합니다. 핵심 포인트는 다음과 같습니다.
- START_STICKY 반환: 시스템이 서비스를 강제 종료하더라도 메모리가 여유로워지면 서비스를 자동으로 재시작합니다.
- onTaskRemoved() 오버라이드: 사용자가 최근 앱 목록에서 앱을 스와이프하여 제거해도 서비스가 다시 시작되도록 처리합니다.
import android.app.Service
import android.content.Intent
import android.os.IBinder
import android.widget.Toast
class MyService : Service() {
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
onTaskRemoved(intent)
Toast.makeText(
applicationContext,
"백그라운드에서 실행 중인 서비스입니다",
Toast.LENGTH_SHORT
).show()
return START_STICKY
}
override fun onBind(intent: Intent): IBinder? {
// 클라이언트와 통신할 채널이 필요하면 여기서 반환하세요.
throw UnsupportedOperationException("Not yet implemented")
}
override fun onTaskRemoved(rootIntent: Intent) {
val restartServiceIntent = Intent(applicationContext, this.javaClass)
restartServiceIntent.setPackage(packageName)
startService(restartServiceIntent)
super.onTaskRemoved(rootIntent)
}
}4단계 — 메인 액티비티 작성 (src/MainActivity.kt)
버튼 클릭 시 서비스를 시작하도록 MainActivity.kt에 아래 코드를 추가합니다.
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title = "KotlinApp"
val button: Button = findViewById(R.id.button)
button.setOnClickListener {
startService(Intent(applicationContext, MyService::class.java))
}
}
}5단계 — 매니페스트에 서비스 등록 (AndroidManifest.xml)
서비스를 사용하려면 반드시 매니페스트 파일에 선언해야 합니다. <application> 태그 안에 아래와 같이 <service> 요소를 추가합니다.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.q11">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MyService"
android:enabled="true"
android:exported="true" />
</application>
</manifest>앱 실행 및 결과 확인
실제 Android 기기를 컴퓨터에 연결한 상태라고 가정하고 앱을 실행해 보겠습니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤 툴바의 Run(실행) 아이콘을 클릭합니다. 실행 대상으로 실제 모바일 기기를 선택하면, 기본 화면이 표시됩니다.

버튼을 클릭하면 서비스가 시작되며 "백그라운드에서 실행 중인 서비스입니다"라는 토스트 메시지가 나타납니다. 앱을 완전히 종료하거나 최근 앱 목록에서 제거해도 onTaskRemoved() 덕분에 서비스가 자동으로 다시 시작되는 것을 확인할 수 있습니다.


참고 사항
Android 8.0(API 26) 이상에서는 배터리 효율 정책 때문에 백그라운드 제약이 강화되었습니다. 장시간 지속적으로 실행해야 하는 작업이라면 일반 서비스 대신 포그라운드 서비스(Foreground Service)로 전환하고, 필수적인 경우에만 사용하는 것이 권장됩니다. 또한 일부 제조사 기기(삼성, 샤오미 등)는 배터리 최적화 기능으로 인해 서비스가 종료될 수 있으므로, 배터리 최적화 예외 설정을 안내하는 것이 좋습니다.