서비스 & Open API

·2021년 11월 24일
0

안드로이드

목록 보기
15/17

눈에 보이지 않고 백그라운드에서 동작한다. 이름 그대로 누군가에게 특정 기능을 제공하는 컴포넌트

서비스의 필요성

서비스를 사용하지 않고 초당 1씩 카운팅하는 기능을 구현한다고 하자.
이떄 메인 스레드에서 5초 이상 작업을 하면 ANR이 발생하게 된다.
문제를 해결하기 위해 작업 스레드를 사용해야 한다.

액티비티 종료

액티비티가 종료된다고 해서 메인 스레드가 종료되는 것은 아니다. 메인 스레드는 루퍼 객체의 loop에서 대기중. 강제 종료가 되어야지만 메인 스레드가 종료된다.

만일 액티비티가 종료되더라도 카운트 기능이 계속 동작하도록 하고 싶은데, 가능할까?

액티비티의 생명주기가 다하면 그 객체 자체도 소멸된다.
유의!! -> 메인 스레드가 종료되지 않았기 때문에 자식 스레드는 종료하지 않는다.
그리고 앱을 다시 실행할 경우 새로 변수와 스레드가 새로 초기화 되게 된다.

서비스는 다른 컴포넌트에 의존하지 않고 백그라운드에서 독립된 동작을 수행한다.
각종 컴포넌트에서 서비스를 제어하거나 원하는 정보를 참조할 수도 있다.
서비스는 프로세스 간 메모리를 공유하거나 원하는 함수를 호출할 수 있도록 하는 IPC, RPC를 지원한다.
2개의 서비스 형태: Started mode, Bound mode

Open API

공공기관이 이용자에게 정보를 재활용 할 수 있도록 제공하고, 제공받은 정보를 상업적, 비영리적으로 이용할 권리를 부여함으로써 다양한 서비스와 데이터를 좀더 쉽게 이용할 수 있도록 공개한 개발자를 위한 인터페이스

JSON

JavaScript Object Notation은 텍스트기반의 데이터 교환 형식
xml보다 간결하며 가독성이 우수하다. 빠르게 읽고 쓰는 것이 가능
데이터 교환언어로 상당한 인기를 얻고 있음
웹서버와 웹 애플리케이션 사이에서 xml 대체 형식으로 많이 사용되고 있음
name/value의 pair로 구성

스타티드 서비스

특정 서비스를 백그라운드로 동작시켜두는 데 목적을 둔 형태의 서비스
서비스를 동작시킨 컴포넌트는 서비스를 중단하는 것 이외에 어떤 제어도 할 수 없다.
동작된 서비스는 알아서 백그라운드로 작업을 수행하고 종료된다.

바운드 서비스

바운드는 외부 라이브러리를 사용하는 것과 매우 유사하다.
LPC와 유사함. 또는 Client Server 모델의 동작과 동일함
서비스로 연결될 컴포넌트는 서비스의 함수들을 마치 라이브러리를 가져다 사용하듯이 쓸 수 있다.
내/외부 앱과 계산 서비스의 관계는 서로 의존적이다.
즉, 서비스를 요청한 컴포넌트가 종료되면 서비스 연결도 끊어진다.

스타티드 서비스와 바운드의 조합 형태 서비스

음악 재생이 필요하면 스타티드 서비스를 이용하여 음악을 재생함
음악 재생서비스는 요청된 음악을 재생한다
재생 중인 앱의 일시 정지 등의 서비스 제어는 바운드 서비스를 통한다.
재생 중인 노래의 정보도 바운드 서비스가 제공한다.

스타티드 서비스의 생명주기

서비스를 생성하면 onCreate 함수 -> onStartCommand 함수가 차례로 호출된다.
서비스가 종료되면 onDestroy 함수가 호출된다.
1. onCreate: 생성 시에만 호출되니 초기화 작업 수행
2. onStartCommand: 서비스가 수행할 동작이 구현됨
3. onStartCommand의 코드가 동작중
4. onDestroy: 서비스가 종료되기 전에 호출됨. 필요하다면 자원을 반환한다.

서비스는 기본적으로 메인 스레드에서 실행되므로 오랜 작업을 수행하면 ANR이 발생한다.

스타트디 서비스의 목적은 백그라운드에서 오랜 시간이 걸리는 작업을 처리하는 것이다.

-> 메인 스레드가 아닌 별도의 작업 스레드에서 처리하게 해야한다.

스타티드 서비스의 생존 우선순위

백그라운드에서 동작 중인 서비스는 stopService 함수를 통해 강제적으로 종료할 수 있다.
stopService 함수를 통하지 않고도 서비스가 종료 될 수가 있다.
-> 메모리가 부족해지면 시스템은 멈춰 버린 다든지 새로운 앱을 실행할 수 없을 수 있다.
-> 기본적으로 안드로이드는 swap space를 사용하지 않는다. 따라서 메모리 제한이 따른다.
-> swap space는 기본 설정 상 disable되어 있다. 원하면 enable 시킬 수 있다.

해결 책: 안드로이드 시스템의 정책
-> 메모리가 부족할 떄 시스템은 다른 앱의 프로세스들을 죽이고 메모리를 확보하게 된다.
-> LMK(Low Memory Killer)가 담당함

LMK는 무작정 앱 프로세스를 강제로 종료하는 것은 아니다.
우선 순위를 통한 LMK의 앱 종료 정책을 통해 가장 우선순위가 높은 앱 프로세스부터 죽인다
-> 우선순위가 높은 앱은 당장 죽여도 큰 문제가 발생하지 않는 앱이다.

상용 리눅스 커널의 프로세스 종료 정책

  • OOM killer 프로세스는 극도로 메모리가 부족하면 프로세스들을 종료시킨다.
  • 유저 프로세스 또는 커널 프로세스를 가리지 않고 적절한 프로세스를 선택한다.
  • OOM killer 동작 시점은 이미 swap space를 포함한 전체 메모리가 거의 full상태가 되었다는 것을 의미함

LMK는 메모리 부족 시에 우선순위를 이용하여 user space에 실행 중이 앱을 종료시킨다.
LMK의 실행에도 불구하고, 극도로 메모리가 부족할 경우에 OOM killer가 실행된다.

LMK 대상이 되는 앱의 우선순위

9번부터 정리된다.

그렇다고 백드라운드 상태인 일반 서비스가 무조건 위험한 것은 아니다
스타티드 서비스가 시작한지 30분 이내는 30분이 지난 다른 서비스보다 안전하다.

서비스의 생존 방법

백그라운드에서 실행되는 서비스가 LMK에 의해 갑자기 종료해버리면 사용자에게 불편을 줄 수 있다.
해결책: 종료 후에 메모리가 충분해지면 재실행 시켜준다.
-> 스타티드 서비스의 onStartCommand 함수 반환값을 START_STICKY로 설정한다.

STRART_STICKY
가용 메모리가 확보되면 다시 서비스를 실행해준다.
START_NOT_STICKY
가용메모리가 확보되어도 다시 서비스를 실행해주지 않는다.

profile

0개의 댓글