240131 TIL #309 Android #22 Service - 1

김춘복·2024년 1월 31일
0

TIL : Today I Learned

목록 보기
309/571

Today I Learned

오늘은 안드로이드 컴포넌트 중 서비스를 공부했다.


Service

서비스는 오래걸리는 작업을 백그라운드에서 처리할 수 있게 해주는 컴포넌트다.

생성 및 실행

  • Service() 클래스를 상속받는다. onBind() 함수는 필수로 구현해야 한다.
class MyService : Service() {
    override fun onBind(intent: Intent): IBinder? {
       return null
    }
}
  • 컴포넌트이므로 매니페스트도 구현해야 한다.
    service 태그로 name 속성은 필수다.
        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true"></service>
  • startService() 함수로 실행
val intent = Intent(this, MyService::class.java)
startService(intent)
stopService(intent) // 실행 종료 함수

// 외부 앱 실행시(단, 백그라운드 상태면 실행 불가)
val intent = Intent("ACTION_OUTER_SERVICE")
intent.setPackage("com.example.test_outer")
startService(intent)
  • bindService() 함수로 실행
    먼저 ServiceConnection를 구현한 객체를 준비하고 두 함수를 재정의한 뒤, 함수를 실행한다.
// ServiceConnection 객체 생성
val connection: ServiceConnection = object : ServiceConnection{
    override fun onServiceConnected(name: ComponentName?, service: IBinder?) { }
    override fun onServiceDisconnected(name: ComponentName?) { }
}
val intent = Intent(this, MyService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
unbindService(connection)

서비스 생명주기

startService()로 실행 시

  • onCreate()가 서비스 객체 생성시 한번만 호출

  • onStartCommand()는 startService() 함수가 실행될 때마다 반복 호출

  • stopService() 함수로 서비스가 종료되면 바로 전에 onDestory() 함수가 호출

bindService()로 실행 시

  • bindService() 함수에서 서비스 객체를 생성하면 onCreate -> onBind() 함수가 호출

  • 다시 bindService() 함수로 실행하면 onBind() 함수만 다시 호출

  • unbindService() 함수로 서비스를 종료하면 onUnbind() -> onDestory() 함수까지 실행


바인딩 서비스

  • startService()는 백그라운드 작업은 필요하지만, 액티비티와 데이터를 주고받을 일이 없는 작업에 유용하다.

  • 반면, 액티비티와 서비스 객체가 상호작용이 필요하다면 bindService()로 객체 바인딩을 하는 것이 유용하다.

  • 서비스 코드의 onBind()함수의 반환 타입은 IBinder 인터페이스다. 이를 구현한 객체를 생성해 반환으로 넘긴다.

class MyService : Service() {
    override fun onBind(intent: Intent): IBinder {
       return MyBinder()
    }
}

class MyBinder: Binder(){
    fun funA(arg: Int){
    }
    fun funB(arg: Int): Int{
        return arg*arg
    }
}
  • 액티비티 코드에선 onBind() 함수에서 반환한 객체를 ServiceConnection 인터페이스를 구현한 객체의 onServiceConnected() 함수로 받을 수 있다.
        val connection: ServiceConnection = object : ServiceConnection{
            override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
                val serviceBinder = service as MyService.MyBinder
            }
            override fun onServiceDisconnected(name: ComponentName?) { }
        }

메신저 바인딩

앞의 IBinder를 구현한 객체를 바인딩하는 방법과 달리, API에서 제공하는 Messenger 객체를 바인딩하는 방법도 있다.

  • 메신저 바인딩은 IPC, 프로세스간 통신에도 사용된다. 외부 앱과 연동해 통신이 가능하다.

  • handleMessage() 함수는 외부에서 서비스에 데이터를 전달할 때 자동으로 호출된다. 이때 외부에서 전달한 데이터는 Message 타입이다.

  • Message의 what값으로는 어떤 성격의 데이터인지를 구분하며 obj 속성으로는 전달된 데이터를 가져온다.

  • onBind() 함수의 반환값으로 Messenger 객체를 생성하면서 생성자 매개변수로 Handler를 구현한 객체를 지정한다.

  • 액티비티 코드에선 onService Connected() 함수의 매개변수로 넘어온 객체를 Messenger의 생성자 매개변수에 지정한다. 서비스 실행 후 데이터를 전달하고 싶을 땐 Messenger.send() 함수를 사용한다.

  • 외부 앱의 서비스를 Messenger 방식으로 bindService() 함수를 이용해 사용하려면 매니페스트에 <intent-filter>를 선언해야 한다.


profile
Backend Dev / Data Engineer

0개의 댓글