Service 컴포넌트를 알아보자

두리두두·2024년 5월 21일

Android

목록 보기
18/25

  • 드디어~. 서비스 컴포넌트까지 왔다.

🔮 서비스란?

  • 백그라운드에서 오래 걸리는 작업을 처리할 수 있게 해주는 컴포넌트.
  • 화면을 구현하지 않는다.
  • 안드로이드 컴포넌트이므로 생명주기를 시스템에서 관리한다.(매니페스트에 등록해야한다. 암시적/명시적 인텐트 모두 가능)
  • 다른 앱의 서비스를 호출할 수도 있다.
  • 어플리케이션 컴포넌트와 서비스를 바인딩하여 상호작용할 수도 있고, 프로세스 통신도 가능하다.
  • 별개의 스레드가 아니며 서비스자체가 스레드도 아니다.

🔮 구현

  • Service 클래스 상속받아서 작성
  • onBind() 함수는 필수
  • 백그라운드 작업은 필요하지만 액티비티와 데이터를 주고받을 일이 없으면 startService(), 서비스와 액티비티 상호작용해야 한다면 bindService()

startService()

  • 액티비티와 데이터 상호작용 X
  • 서비스를 인텐트에 담아서 전달 후 startService(intent)
  • 외부 앱의 서비스라면 암시적 인텐트로 실행해야하므로, setPackage() 함수로 패키지명 명시.
val intent = Intent("ACTION_OUTER_SERVICE")
intent.setPackage(com.example.test_outer")
startService(intent)
  • 다른 컴포넌트와 다르게 실행 중인 서비스를 종료하는 함수도 있다.
val intent = Intent(this, MyService::class.java)
stopService(intent)

bindService()

  • 액티비티 데이터와 상호작용 O
  • bindService(인텐트, serviceConnection 객체, 플래그)로 사용해야 하므로 두번째 매개변수 객체를 준비해야한다.
val connection: ServiceConnection = object : ServiceConnection {
	override fun onServiceConnected(name: ComponentName?, service: IBonder?){}
    override fun onServiceDisconnected(name: ComponentName?){}
    }
  • 추상 함수 두 개는 각각 bindService(), unbindService() 함수로 서비스를 구동/종료할 때 자동으로 호출된다. (재정의 해야함)
val intent = Intent(this, MyService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
  • 세번째 매개변수는 int 타입의 플래그. 대부분 Context.BIND_AUTO_CREATE 사용한다. 서비스가 실행 상태 아니더라도 객체 생성해서 실행하라는 뜻!
  • unbindService(connection)으로 서비스 종료할 수 있음.

🔮 바인딩?!

  • bindService()를 사용하면 서비스 생명주기 함수에서 onBind()가 실행되는데, 반환타입이 IBinder 인터페이스이다.
  • 서비스에서 IBinder를 만들어두면, 서비스를 호출한 곳에서 IBinder를 리턴받고, IBinder 클래스의 함수를 호출하면서 매개변수와 반환값으로 데이터를 주고 받는다.

서비스 코드

class MyBinder : Binder(){
	fun funA(arg: Int){
    }
    fun funB(arg : Int){
    	return arg*arg
    }
}

// 생명주기에서 onbind호출되고, IBinder타입 반환
override fun onBind(intent: Intent): IBinder? {
	return MyBinder()
}

액티비티 코드

  • 위에서 리턴해준 IBinder 타입의 객체를 서비스 호출한 곳인 액티비티에서는 onServiceConnected 함수(bindService() 될 때 자동호출!!!)로 받을 수 있다.
val connection: ServiceConnection = object : ServiceConnection {
	// 아까 위에서 재정의해줘야 한다는 부분! 자동호출되며 서비스바인더 설정
	override fun onServiceConnected(name: ComponentName?, service: IBinder?){
    	serviceBinder = service as MyService.MyBinder
   }
   override fun onServiceDisconnected(name: ComponentName?){//...재정의 필요...//}
    }
    
  ...
  
  // 이런 식으로 사용
  serviceBinder.funA(10)

그냥 intent.putExtra 쓰면 안되나?

  • 데이터 주고받을 때 엑스트라 데이터를 사용하면 되지 않나.싶지만 이는 인텐트로 특정 컴포넌트를 실행할 때 전달해야하는 데이터를 의미한다. 반면, 바인드 서비스는 인텐트로 이미 서비스가 실행된 상태에서 발생하는 데이터를 주고받는 방법이다.
  • 서비스 실행한 곳에서는 IBinder 객체를 바인딩할 수도 있지만, API에서 제공하는 Messenger 객체를 바인딩 할 수도 있다.

  • 요건 다음 시간에..일단 지금은 출근을 위해 자야함 ㅜ.ㅜ

  • 그럼 20000

profile
야금야금 앱 개발자

0개의 댓글