본문 바로가기

안드로이드

service

service : 백그라운드에서 장기실행이 가능한 구성요소로  사용자 인터페이스를 제공하지 않는다. 

service를 사용해야 하는 이유는 1. 구성요소의 생명주기와 스레드 생명주기의 분리 2. 호스팅 프로세스의 생명주기 때문이다. 

메모리 누수에 의한 위험과 너무 빨리 태스크가 종료될 위험 모두 줄일 수 있다. 

1. 기본 동작 방식   

(1) 시작됨 - startservice -> onstartcommand

(2) 바인드됨 - bindservice -> onBind -> 클라이언트는 serviceconnection구현

** 서비스는 기본적으로 메인(UI)스레드에서 실행된다. 서비스가 시스템에 의해 종료되지 않는 경우는 포그라운드 액티비티와 바인딩되어 있는 경우 

포그라운드 서비스일경우 거의 종료되지 않음

 onstartcommand 리턴값 

  (1) START_NOT_STICKY : 재생성하지 않는다. (2) START_STICKY : 재생성이나 마지막 인텐트를 다시 전달하지 않는다. 

  (3) START_REDELIVER_INTENT : 재생성 후 마지막 인텐트를 전달한다. 

 bindservice를 만들려면 ibinder 구현하여 onbind에서 반환한다. 클라이언트는 ibinder를 수신하여 서비스와 상호작용한다. 

2. 종류 

(1) 지역서비스 : 같은 프로세스내 서비스, 공유된 객체를 통해 통신한다. 

(2) 전용원격서비스 : 다른 프로세스이나 같은 앱내의 구성요소에 접근가능하다. 

(3) 전역원격서비스 : 다른 프로세스이고 service이름으로 참조불가능하다. 인텐트 필터를 통해 접근이 가능하다. 


** 백그라운드 서비스 

(1) jobintentservice : android 8.0 미만에서 백그라운드서비스로 적재된 작업이 순차적으로 실행된다. 

                           android 8.0 이상에서는 jobscheduler를 통해 적재된 작업이 순차적으로 실행된다. 

   1) intent를 생성하여 jobintentservice를 콜한다. 2) enqueue work를 콜한다. 


(2) intentservice : 작업자스레드를 사용하여 요청을 처리하며 순차처리를 하므로 다중스레딩 염려가 없다. 

   onHandleIntent에서 구현하고 stopself안해도 작업이 끝나면 알아서 종료된다. 

   제한 사항 1) UI와 상호작용할수 없으므로 결과를 액티비티에 보내야한다. 

                2) 순차 실행 


** 작업 상태 보고 : 백그라운드서비스에서 실행되는 작업 요청의 상태를 요청을 보낸 구성요소에 보고 하는 방법을 보여준다. 

  LocalBroadcastManager.getInstance(this).sendBroadcast(localintent);

3. BindService - 클라이언트가 서비스와 상호작용하는데 사용할 수 있는 프로그래밍 인터페이스를 제공하는 IBinder제공

                     (1) Binder클래스를 확장 : 같은 프로세스일때 가능

                         - Binder클래스를 상속하고 그 인스턴스를 onBind에서 반환, 클라이언트가 binder를 받아 binder를 구현후 공개메서드에 직접 액세스

                     (2) messenger 사용 : 다른 프로세스이나 멀티 스레딩을 지원하지 않는다. 

                        - 클라이언트로부터 각 호출에 대해 콜백을 받는 handler구현하고 이를 이용해 messenger를 구현해 ibinder를 onbind에서 반환하고 

                          클라이언트는 ibinder를 사용하여messenger 인스턴스화 하고 이를 이용하여 messege를 서비스에 전송한다. 서비스는 message를 

                          handler를 통해 전달받는다. 

                    (3) aidl 사용 : 다른 프로세스고 멀티스레드를 지원한다. 

                        - 한 프로세스가 다른 프로세스의 메모리에 정상적으로 액세스할 수  없기에 객체들을 OS가 이해할수있는 원시유형으로 해체하고

                          해당 경계에 걸쳐 마샬링한다. 이 마샬링을 위해 코드를 작성해야 하는 일을 안드로이드는 aidl을 이용하여 대신해준다. 

                         AIDL은 직접 함수호출이다. 

                         1) aidl 파일 생성 

                         2) 인터페이스 구현 : aidl 파일이름을 딴 java인터페이스 파일을 생성하는데 상위 인터페이스의 추상구현인 STUB이라는 서브클래스를 

                                                    포함하여 aidl파일에 있는 모든 메서드 구현

                         3) 클라이언트에 인터페이스 노출 - onbind로 ibinder 반환

                         4) 클라이언트는 serviceconnection에서 interface명.stub asinterface로 서비스를 받는다. 

                         5) 전송하길 원하는 클래스는 parcelable해야한다. (마샬링할수있는 원시유형으로 해체할수있기 때문)