안드로이드 16) Service

밍나·2022년 1월 25일
0

Android

목록 보기
16/36

Concepts of Service

1. Service

  • 백그라운드에서 오랜 시간동안 수행되는 업무를 처리하기 위한 컴포넌트
    • 액티비티에서도 Thread나 Coroutine을 이용해 백그라운드에서 업무 수행이 가능
    • 위의 것들은 화면 반응성이 있는 백그라운드 업무(수행 결과가 화면에 찍히는 등..)
    • 서비스는 화면 반응성이 없거나 아주 드물게 발생하는 백그라운드 업무만 담당
    • 또한 다른 애플리케이션이 작동 중이어도 우리 애플리케이션이 작동해야하는 것이 있는 경우 담당
  • 화면 출력 능력은 가지지 않는 컴포넌트

2. Service 사용 방법
1) Service를 상속받아 작성

class MyService: Service() {
    override fun onBind(intent: Intent): IBinder? {
    	return null
    }
}
  • 특정 기능이 추가된 Service의 서브 클래스를 상속받아 작성하기도 함

2) AndroidManifest.xml에 등록

<service
    android:name=".MyService"
    android:enabled="true"
    android:exported="true"></service>
  • name 속성 생략 불가
  • Service 또한 Intent로 실행되는데 명시적 인텐트로 실행시키려면 name만 써도 되지만 암시적 인텐트로 실행시키려면 intent filter 작성 필요

3) startService()에 의해 Service 실행

val intent = Intent(this, MyService::class.java)
startService(intent)
  • 외부 앱의 서비스라면 setPackage() 함수를 이용해 실행하고자 하는 앱의 패키지명(식별자) 명시

4) stopService()에 의해 Service 종료

val intent = Intent(this, MyService::class.java)
stopService(intent)
  • 화면 반응성이 없어 유저에 의해 종료될 수 없기 때문에 필요 없는 순간 코드에서 종료

Service Lifecycle

1. Activity Lifecycle vs Service Lifecycle

  • 안드로이드 4대 컴포넌트 중 Activity와 Service는 Lifecycle 정리를 해주어야 함
  • 서비스를 실행시키는 방법이 startService() 함수와 bindService() 함수 두개가 있음
  • 어느 함수를 이용해 서비스가 실행되는지에 따라 서비스의 라이프 사이클이 다름
  • 서비스 클래스는 싱글톤으로 동작
    • 싱글톤 : 하나의 클래스가 동작할 때 단 하나의 객체로만 동작
    • 액티비티 클래스에 인텐트를 발생 시켜 액티비티를 실행 → 액티비티 객체가 생성되어서 동작 → 똑같은 액티비티를 실행시키기 위한 인텐트가 한번 더 발생하면? → 액티비티는 싱글톤으로 동작하지 않기 때문에(액티비티는 화면 출력 목적이기 때문에) 또 하나의 객체가 발생
    • 서비스 클래스에 인텐트를 발생 시켜 서비스를 실행 → 서비스 객체가 생성되어서 동작 → 똑같은 서비스를 실행시키기 위한 인텐트가 한번 더 발생하면? → 객체가 다시 생성되지 않고 이전에 생성된 객체를 그대로 이용(서비스는 화면 출력 목적이 아니기 때문에)

2. Service Lifecycle
1) startService()로 구동

  • 객체 생성 → Oncreate() 호출 → onStartCommand() 호출 → 서비스 실행 → stopService()로 인텐트 발생 → onDestroy() 호출 → 서비스 종료
  • 하나의 서비스가 실행되고 있는데 같은 서비스를 실행시키기 위한 인텐트가 발생해도 객체를 발생시키지 않음 → onCreate()는 서비스 객체 생성 때 한번만 호출, onStartCommand()만 다시 호출(매개변수에 호출시킨 인텐트가 들어감)
  • 인텐트가 발생되어 요청이 들어올 때마다 onStartCommand()에서 쓰레드를 하나씩 만들어서 멀티쓰레드 환경으로 프로그램이 동작되는 등의 처리를 해주면 됨

2) bindService()로 구동

  • 객체 생성 → Oncreate() 호출 → onBind() 호출 → 서비스 실행 → unbindService()로 인텐트 발생 → onUnbind() 호출 → onDestroy() 호출 → 서비스 종료
  • 하나의 서비스가 실행되고 있는데 같은 서비스를 실행시키기 위한 인텐트가 발생해도 객체를 발생시키지 않음 → onCreate()는 서비스 객체 생성 때 한번만 호출, onBind()만 다시 호출, 종료시 onUnbind()도 요청 단위대로 호출

startService

1. startService

  • 서비스 구동을 위해 인텐트를 발생시켜야 함, 인텐트를 발생시키는 함수가 startService()
  • startService()에 의해 Service가 실행되면 특정 객체가 리턴되지 않는다
    • 상호 데이터를 전달할 직접적인 방법이 없다, 즉 인텐트에 의해 발생된 후에 서비스를 구동시킨 곳(액티비티, 리시버, 다른 서비스 등)과 데이터를 서로 전달할 방법이 없다
    • 데이터를 전달 받을 곳에 BroadcastReceiver를 정의하고 데이터 전달이 필요할 때 이 BroadcastReceiver를 실행시키면 Broadcast Intent에 Extra 데이터로 전달시키는 방법을 이용

2. 데이터 전달 예시

  • 액티비티에서 유저 이벤트나 유저가 등록한 데이터를 서비스에 전달하는 경우
    ① Intent에 extra data로 데이터를 담는다
    ② Intent를 발생시켜서 Service 내부의 BroadcastReceiver가 실행되도록 한다
    ③ BroadcastReceiver에서 extra data를 추출해서 Service에서 이용
  • 서비스에서 데이터를 액티비티에 전달하는 경우
    ① Intent에 extra data로 데이터를 담는다
    ② Intent를 발생시켜서 Activity 내부의 BroadcastReceiver가 실행되도록 한다
    ③ BroadcastReceiver에서 extra data를 추출해서 Activity에서 이용

bindService

1. bindService

  • bindService()는 서비스가 실행되면서 자신을 실행시킨 곳에 객체를 바인딩한다는 의미
  • 서비스를 구동시킨 결과를 자신을 실행시킨 곳에다가 객체를 넘겨준다(바인딩한다)
  • 서비스를 구동시킨 곳에 객체를 넘겨주고 그 객체에 있는 함수를 호출하면서 매개변수 혹은 리턴값으로 서비스와 서비스를 구동시킨 곳에서 서로 데이터를 주고 받을 수 있음

2. bindService 사용
(1) 서비스의 라이프사이클 함수 중 onBind() 함수가 실행

class MyBinder: Binder() {
    fun funA(arg: Int){
    
    }
    fun funB(arg: Int): Int{
    	return arg*arg
    }
}
override fun onBind(intent: Intent): IBinder? {
    return MyBinder()
}
  • Binder를 상속받은 클래스를 준비하고 이 클래스의 객체를 리턴
  • Binder를 상속받은 클래스 내부의 함수의 매개변수나 리턴값으로 서비스를 구동시킨 곳과 데이터를 주고 받음
    (2) 서비스를 구동시키는 곳
val connection: ServiceConnection = object: ServiceConnection{
    override fun onServiceConnected(name: ComponentName?, service: IBinder?){
    	serviceBinder = service as MyService.MyBinder
    }
    
    override fun onServiceDisconnected(name: ComponentName?){
    }
}
  • ServiceConnection을 구현한 객체 준비
  • onServiceConnected() 함수의 매개변수로 서비스에서 보낸 Bind 객체 전달
profile
🤗🤗🤗

0개의 댓글