[Android] Service

๐Ÿ’ก์•ˆ๋“œ๋กœ์ด๋“œ 4๋Œ€ ์ปดํฌ๋„ŒํŠธ ์ค‘ ํ•˜๋‚˜์ธ Service์— ๋Œ€ํ•˜์—ฌ ์ •๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

Service

  • Service๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์‹คํ–‰๋˜๋Š” ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋ฉฐ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํฌ๊ทธ๋ผ์šด๋“œ์— ์—†์–ด๋„ ๊ณ„์†ํ•ด์„œ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ฃผ๋กœ ๋„คํŠธ์›Œํฌ ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ, ์Œ์•… ๊ฐ™์€ ์žฅ๊ธฐ ์‹คํ–‰ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

์„œ๋น„์Šค ๊ฐœ์š”  |  Background work  |  Android Developers

 

์„œ๋น„์Šค ๊ฐœ์š”  |  Background work  |  Android Developers

์ด ํŽ˜์ด์ง€๋Š” Cloud Translation API๋ฅผ ํ†ตํ•ด ๋ฒˆ์—ญ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์„œ๋น„์Šค ๊ฐœ์š” ์ปฌ๋ ‰์…˜์„ ์‚ฌ์šฉํ•ด ์ •๋ฆฌํ•˜๊ธฐ ๋‚ด ํ™˜๊ฒฝ์„ค์ •์„ ๊ธฐ์ค€์œผ๋กœ ์ฝ˜ํ…์ธ ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ถ„๋ฅ˜ํ•˜์„ธ์š”. Service๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์„ฑ์š”์†Œ ์žฅ๊ธฐ ์‹ค

developer.android.com

๋ณ„๋„์˜ ์Šค๋ ˆ๋“œ

  • ๊ณต์‹๋ฌธ์„œ์—๋Š” ์„œ๋น„์Šค ์‚ฌ์šฉ ์‹œ ์ฃผ์˜์‚ฌํ•ญ์œผ๋กœ ์•„๋ž˜ ๋‚ด์šฉ์„ ๋ช…์‹œํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์„œ๋น„์Šค๋Š” ๋ณ„๋„์˜ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š์œผ๋ฉด ํ˜ธ์ŠคํŒ… ํ”„๋กœ์„ธ์Šค์˜ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ฆ‰ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ์ž‘์—…์„ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฉˆ์ถ”๊ณ  ANR ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Foreground Service

  • Foreground Service๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ช…ํ™•ํžˆ ์ธ์‹๋˜๋ฉฐ, ์•Œ๋ฆผ์„ ํ†ตํ•ด ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ž‘์—… ์ค‘์ž„์„ ํ‘œ์‹œํ•˜๋Š” ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.
  • ์Œ์•… ์žฌ์ƒ, ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ, GPS ์ถ”์ ๊ณผ ๊ฐ™์€ ์ž‘์—…์— ์‚ฌ์šฉ๋˜๋ฉฐ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋‚ฎ์•„ ์‹œ์Šคํ…œ ๋ฆฌ์†Œ์Šค๊ฐ€ ๋ถ€์กฑํ•˜๋”๋ผ๋„ ์‰ฝ๊ฒŒ ์ข…๋ฃŒ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์„œ๋น„์Šค๋ฅผ ์ค‘์ง€ํ•˜๊ฑฐ๋‚˜ ํฌ๊ทธ๋ผ์šด๋“œ์—์„œ ์ œ๊ฑฐํ•˜์ง€ ์•Š๋Š” ํ•œ ์•Œ๋ฆผ์„ ํ•ด์ œํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
class MyForegroundService : Service() {

    override fun onCreate() {
        super.onCreate()
        val notification = NotificationCompat.Builder(this, "channel_id")
            .setContentTitle("Foreground Service")
            .setContentText("Running in the foreground")
            .setSmallIcon(R.drawable.ic_notification)
            .build()

        startForeground(1, notification) // Foreground ์„œ๋น„์Šค ์‹œ์ž‘
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—… ์ˆ˜ํ–‰
        return START_STICKY
    }

    override fun onDestroy() {
        super.onDestroy()
    }

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }
}

Background Service

  • ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ์ธ์‹ํ•˜์ง€ ์•Š๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์‹คํ–‰๋˜๋Š” ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.
  • Android 8.0 ์ด์ƒ์—๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์‹คํ–‰์— ์ œํ•œ์ด ์žˆ์–ด, ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…์„ WorkManager ๋˜๋Š” Foreground Service๋กœ ๋Œ€์ฒดํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
val serviceIntent = Intent(this, MyBackgroundService::class.java)
startService(serviceIntent)

Bound Service

  • Activity, Fragment์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปดํฌ๋„ŒํŠธ์™€ ๋ฐ”์ธ๋”ฉ๋˜์–ด ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.
  • ์ฃผ๋กœ ํด๋ผ์ด์–ธํŠธ - ์„œ๋ฒ„ ๊ตฌ์กฐ์—์„œ ์‚ฌ์šฉ๋˜๋ฉฐ, ์„œ๋น„์Šค๋Š” ์ƒ๋ช…์ฃผ๊ธฐ๊ฐ€ ํด๋ผ์ด์–ธํŠธ์— ์ข…์†๋ฉ๋‹ˆ๋‹ค.
  • Activity ๋˜๋Š” Fragment๊ฐ€ ์„œ๋น„์Šค์™€ ๋ฐ”์ธ๋”ฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
class MyBoundService : Service() {

    private val binder = LocalBinder()

    inner class LocalBinder : Binder() {
        fun getService(): MyBoundService = this@MyBoundService
    }

    override fun onBind(intent: Intent?): IBinder {
        return binder
    }

    fun performTask(): String {
        return "Task completed"
    }
}

// Activity์—์„œ ๋ฐ”์ธ๋”ฉ
class MyActivity : AppCompatActivity() {
    private lateinit var service: MyBoundService
    private var bound = false

    private val connection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName, binder: IBinder) {
            val localBinder = binder as MyBoundService.LocalBinder
            service = localBinder.getService()
            bound = true
        }

        override fun onServiceDisconnected(name: ComponentName) {
            bound = false
        }
    }

    override fun onStart() {
        super.onStart()
        Intent(this, MyBoundService::class.java).also { intent ->
            bindService(intent, connection, Context.BIND_AUTO_CREATE)
        }
    }

    override fun onStop() {
        super.onStop()
        if (bound) {
            unbindService(connection)
            bound = false
        }
    }
}

์„œ๋น„์Šค ์ƒ๋ช…์ฃผ๊ธฐ

  • ์„œ๋น„์Šค๋Š” ์ƒ๋ช…์ฃผ๊ธฐ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

onCreate

  • ์„œ๋น„์Šค๊ฐ€ ์ฒ˜์Œ ์ƒ์„ฑ๋  ๋•Œ ํ˜ธ์ถœ๋˜๋ฉฐ, ์ดˆ๊ธฐํ™” ์ž‘์—…์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

onStartCommand

  • ์„œ๋น„์Šค๊ฐ€ ์‹œ์ž‘๋  ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
  • ์ฃผ๋กœ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…์„ ์‹œ์ž‘ํ•˜๋Š” ๊ณณ์ด๋ฉฐ, ์„œ๋น„์Šค์˜ ๋™์ž‘ ๋ฐฉ์‹์„ ๊ฒฐ์ •ํ•˜๋Š” ๋ฐ˜ํ™˜ ๊ฐ’์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
  • START_STICKY : ์„œ๋น„์Šค๊ฐ€ ๊ฐ•์ œ๋กœ ์ข…๋ฃŒ๋˜์–ด๋„ ์‹œ์Šคํ…œ์ด ์žฌ์‹œ์ž‘์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.
  • START_NOT_STICKY : ๊ฐ•์ œ ์ข…๋ฃŒ๋œ ์„œ๋น„์Šค๋Š” ๋‹ค์‹œ ์‹œ์ž‘๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • STRAT_REDELIVER_INTENT : ์„œ๋น„์Šค๊ฐ€ ๊ฐ•์ œ ์ข…๋ฃŒ๋œ ๊ฒฝ์šฐ, ๋งˆ์ง€๋ง‰ ์ธํ…ํŠธ๋ฅผ ๋‹ค์‹œ ์ „๋‹ฌ ๋ฐ›์Šต๋‹ˆ๋‹ค.

onBind

  • ๋ฐ”์šด๋“œ ์„œ๋น„์Šค์—์„œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฐ”์ธ๋”ฉํ•  ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

onUnBind

  • ๋ฐ”์šด๋“œ๋œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฐ”์ธ๋”ฉ์„ ํ•ด์ œํ•  ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

onDestroy

  • ์„œ๋น„์Šค๊ฐ€ ์ข…๋ฃŒ๋˜๊ธฐ ์ง์ „์— ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

์ •๋ฆฌ

  • Service๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ค‘์š”ํ•œ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.
  • Foreground Service๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ช…ํ™•ํžˆ ์ธ์‹๋˜๋Š” ์ž‘์—…์— ์ ํ•ฉํ•˜๋ฉฐ, Background Service๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์ด์ง€ ์•Š์€ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • Bound Service๋Š” ํด๋ผ์ด์–ธํŠธ - ์„œ๋ฒ„ ๊ตฌ์กฐ์—์„œ ์‚ฌ์šฉ๋˜๋ฉฐ ํŠน์ • ์ปดํฌ๋„ŒํŠธ์— ๋ฐ”์ธ๋”ฉ๋˜์–ด ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • Android 8.0๋ถ€ํ„ฐ๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์„œ๋น„์Šค ์‚ฌ์šฉ์— ๋Œ€ํ•œ ์ œ์•ฝ์ด ๊ฐ•ํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด Foreground Service๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ WorkManager์™€ ๊ฐ™์€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—… ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.