티스토리 뷰

Android

안드로이드 노트: 서비스, 생존주기, startService(), bindService(), ANR, AIDL, RPC

rhys
반응형

[Android App Dev. for Beginners] Services



안드로이드 서비스 https://developer.android.com/guide/components/services.html?hl=ko

안드로이드 App을 구성하는 4가지 컴포넌트 중 하나

액티비티와 유사하게 동작하나 UI, 화면이 없고 백그라운드에서 실행됨

Service는 OOM(Out of Memory Killer)에 의해 죽을 가능성이 Activity Process 상태보다 훨씬 적다


ex) 음악 플레이어, 서버에 데이터 요청 후 응답을 기다리는 작업, 리시버 대기하는 채팅 앱, 바이러스 감시, 장치연결 대기



서비스 라이프사이클 - 생존주기



startService() ▶, ■

AndroidManifest.xml에 서비스 선언 후 startService(), stopService() 콜백함수 구현

Intent를 넣어 호출하는데, 안드로이드 5.0 이후로는 명시적 인텐트만을 이용할 수 있도록 보안이 강화됨

시작/종료 외에는 사용자가 임의로 서비스를 제어 불가, 서비스를 호스팅하는 어플리케이션에서만 접속 가능

'백그라운드 데몬'



문제: 메모리 부족시 서비스 종료 - startService()

서비스는 메모리가 부족하지 않다면 계속 백그라운드에 떠 있으나, 메모리가 부족한 경우 제거될 수 있음


1) Foreground Service로 설정하여 우선순위를 높인다: startForeground() / stopForeground()

- 사용자가 활발하게 사용하는 서비스로 간주되어 메모리 부족시 제거후보가 되지 않음

- 시스템 자원 안정화를 위해 중요한 서비스일 경우에만 사용


2) 강제종료시 대응할 동작을 설정하여, 메모리 확보가 되면 살아나도록 대비

- onStartCommand()의 반환값과 두 번째 인수(flags)를 통해 상황 제어가능


START_STICKY: 5초 후 Service를 재시작하며 'null intent'로 onStartCommand() 호출

START_NOT_STICKY: 인텐트가 올때까지 Service를 재생성하지 않음

START_REDELIVER_INTENT: 40초 후 전달된 '마지막 Intent'로 Service를 재시작


3) 제조사가 선택할 수 있는 옵션

AndroidManifest.xml에서 android:persistent="true" 설정 후 System패키지 속성 부여

Foreground보다 정리되지 않을 우선순위가 훨씬 높음

일반 개발자는 루팅이 필요해 시도가 무의미



Main Thread와 분리 필요


문제: ANR(Android Not Responding)

메인스레드에서 20초 이상 걸리는 작업을 하게되면 시스템에서 ANR을 발생시킴

서비스의 모든 콜백 함수들은 메인스레드에 의해 처리되기 때문에, ANR 발생 위험이 있다

따라서 오랜 작업시간이 우려되는 연산은 별도의 스레드를 구현하여 처리가 필요


메인스레드? UI Thread. 프로세스의 메인 함수로서 실행되는 스레드: Thread[<1> main] 화면과 직접 연관되는 액티비티가 메인스레드로 생성됨

일반스레드? 메인 또는 다른 스레드들로 부터 생성된 스레드



bindService() ▶, ■, II, ≪, ≫

둘 모두 Service Class에서 파생되어 작성되었으나 지속성이 있는 작업(startService) / Library와 유사하게 가져다 쓸 수 있는 유형(bindService)로 구분됨

그러나 서비스가 어느 것에 의해 시작되건 간에, 서비스는 잠재적으로 클라이언트가 바인드 하는 것을 허용할 수 있음

API를 통해 사용자가 서비스를 제어 가능, 다른 어플리케이션에서 통로를 통해 원격으로 접속 가능

모든 연결된 컴포넌트가 연결을 해제하면 서비스가 소멸

'원격 인터페이스 호출'



문제: 메모리 부족시 서비스 종료 - bindService()

bindService() 호출시 Flag 설정

BIND_AUTO_CREATE: 시스템에 의해 강제로 종료되면 Intent를 다시 전달받으며 재시작


*bindService()는 onStartCommand()가 없음




Process A가 B에 위치한 sum() 함수를 사용하고 싶어 하는 상황

조립/분해 설명서 AIDL은 Process A, Process B 모두에 있어야 함


*Linux 커널은 하나의 Process가 다른 Process에 영향을 절대 줄 수 없도록 메모리 공유를 절대적으로 차단



AIDL(Android Interface Definition Language)

앞의 bindService() 설명에서, 해당 어플리케이션 이외의 범위에서도 서비스를 사용할 수 있게 하는 부분

Android 내부에서 사용되는 RPC Interface 정의 언어

서비스를 상용하는 클라이언트에게 제공되는 인터페이스를 정의


1. AIDL 설정

2. 서비스 쪽에서 AIDL을 구현하고 매니페스트를 설정하여, 다른 클라이언트가 사용할 수 있도록 함

3. 클라이언트에서 AIDL을 사용하여 서비스 호출 준비



출처: http://cafe.daum.net/superdroid


반응형

댓글