총 게시물 15건, 최근 0 건
   
[휴님강좌]

[번역] 안드로이드 2.0 에서 변경된 Service API

글쓴이 : huewu 날짜 : 2010-07-26 (월) 18:55 조회 : 15621
글주소 : http://www.androidside.com/B46/12226
 
  아이티뱅크 자바교육 전진홍
자바 교육센터, 안드로이드2.0, 자바 교육상담 환영.
www.itbank-edu.co.kr
  임베디드 시스템 마이크로비젼
임베디드 개발보드, 개발용역, IAR 컴파일러 총판, 에뮬레이터.
www.mvtool.co.kr
  아이티뱅크 자바교육 김민지
IT 교육센터, 안드로이드2.0, 기초부터 고급까지 책임교육.
www.it-bank.co.kr
클릭초이스 등록


안드로이드 어플리케이션 개발에서 가장 까다로운 일 중 하나는 바로 Service 를 적절하게 사용하는 일이 아닐까 합니다. 어떤 작업을 백그라운드에서 안적정으로 동작하기 위해 Service 를 사용하기는 쉽지만, 한번 시작된 Service 의 생명주기를 잘 관리해서, 사용자에게 더이상 필요 없을 시점에 적절하고 확실하게 종료시키거나 하는 일은 쉽지 않지요. 뭐, 안드로이드 폰을 사용하다보면 속도가 느려진다는 사용자들의 불만 중 많은 부분이, 이 Service 를 적절하게 사용하지 못한 어플리케이션의 탓이 아닐까 생각합니다. 안드로이드 버전 2.0 부터는 보다 손쉽게 Service 의 생명주기를 관리할 수 있는 API 들이 추가되었는데요, 안드로이드 개발자 블로그에 올라온 글을 번역한 내용을 공유해 봅니다.

Service API changes starting with Android 2.0
  • Service.setForeground() 가 더 이상 작동하지 않음. (Deprecated)
  • 상황에 따라 더 이상 필요하지 않은 Service 가 죽지 않는 경우가 많았는데, 이런한 에외사항을 보다 잘 처리할 수 있도록 새로운 API 를 제공함.
  • 사용자들이 현재 시스템에서 작동 중인 Service 를 확인하고 관리할 수 있는 UI 를 제공.
Background on services

  서비스 API 는 어플리케이션이 백그라운드에서 특정 작업을 수행할 수 있게 해주는.안드로이드의 핵심 매커니즘의 하나이다. 안드로이드 플랫폼 특성상, 화면상에 표시되지 않은 개별 어플리케이션은 시스템이 종료시키고, 필요한 경우 다시 시작할 수 있다고 여겨진다. 따라서 특정 어플리이션이 백그라운드에서도 특정 일을 수행할 필요가 있을 경우, Service 를 시작해야 하며, 시스템은 Service 를 구동중인 어플리케이션은 강제로 종료시키지 않는다. (최대한...)

   Service 는 매우 유용한 수단이지만, 언제나 권한에는 책임이 뒤 따른다. (power comes some responsibility). Service 를 가동하고 있는 어플리케이션은 시스템 자원을 소모기 때문에 전반적인 시스템 성능에 문제를 일으킬 수 있다. 따라서 개발자들은 정말로 필요한 경우에만 Service 를 사용해야 하며, 필요없는 Service 가 백그라운드에 남아있지 않도록 주의를 기울여야 한다. (서비스 릭 버그를 내지 말아야 한다...)

Redesigning Service.setForeground()

 Androi 1.6 안정화 기간동에, 너문 많은 어플리케이션이 Service.setForeground() API 를 사용하기 때문에 발생하는 문제들이 발견되었다.  이 API가 호출 되면,  시스템은 특정 Service가 구동중인 프로세스가 포그라운드 프로세스로 간주한다. (우선 순위 부여)  따라서, 시스템이 메모리 부족등의 예외 상황을 처리하게 매우 어렵게 만든다. 

  이러한 문제점이 발견된 시점이 너무 늦었기에, 1.6 버전 SDK는 이 API에 대하여 큰 변화 없이 공개되었지만, 2.0 에서는 중요한 변경사항이 이루어졌다. Service.setForeground() 는 이제 작동하지 않는다. 따라서 기존의 API 를 대체해서 2.0 버전에서는 두가지  새로운 API 가 추가되었다. 이제 Service 가 포그라운드로 진입하고자 할  경우, 사용자가 해당 사실을 확인하고 필요한 경우, 포그라운드에서 작동중인 서비스를 정지 시킬 수 있도록, Notification 을 보내야 한다. (주> 음악 재생 서비스 와 같이, 상태바에 특정 메세지를 표시하도록...)
 
public final void startForeground(int id, Notification notification);

public final void stopForeground(boolean removeNotification);
 
 시스템은 Service 가 포그라운드에서 작동 중이라면, 어떠한 형태든 Notification 이 남아 있음을 확신 할 수 있고 따라서, Service 와 연관된 Notification 상태를 쉽게 관리 할 수 있다.  당연히, 많은 개발자들이 2.0 뿐만 아니라 이전 플랫폼에서도 작동하는 Service 코드를 작성하고 싶어한다. 아래와 같이 가능한 경우에 한해서 새롭게 추가된 API 를 호출하는 방법으로 예전 버전과 2.0 이후 버전에서 모두 작동하는 코드를 작성 할 수 있다.

private static final Class[] mStartForegroundSignature = new Class[] {
int.class, Notification.class};
private static final Class[] mStopForegroundSignature = new Class[] {
boolean.class};

private NotificationManager mNM;
private Method mStartForeground;
private Method mStopForeground;
private Object[] mStartForegroundArgs = new Object[2];
private Object[] mStopForegroundArgs = new Object[1];

@Override
public void onCreate() {
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
try {
mStartForeground = getClass().getMethod("startForeground",
mStartForegroundSignature);
mStopForeground = getClass().getMethod("stopForeground",
mStopForegroundSignature);
} catch (NoSuchMethodException e) {
// Running on an older platform.
mStartForeground = mStopForeground = null;
}
}


void stopForegroundCompat(int id) {
// If we have the new stopForeground API, then use it.
if (mStopForeground != null) {
mStopForegroundArgs[0] = Boolean.TRUE;
try {
mStopForeground.invoke(this, mStopForegroundArgs);
} catch (InvocationTargetException e) {
// Should not happen.
Log.w("MyApp", "Unable to invoke stopForeground", e);
} catch (IllegalAccessException e) {
// Should not happen.
Log.w("MyApp", "Unable to invoke stopForeground", e);
}
return;
}

// Fall back on the old API. Note to cancel BEFORE changing the
// foreground state, since we could be killed at that point.
mNM.cancel(id);
setForeground(false);
}

Service lifecycle changes

 Service 들이 필요하지 않은 경우에도 불구하고, 자신을 포그라운드 프로세스로 설정하는 문제를 제외하고도,  백그라운드에서 너무 많은 수의 Service 들이 돌아감에 따라, 각각의 Service 들이 한정된 메모리 자원을 차지하게 위해 서로 경쟁하게 되면 또 다른 문제가 발생할 수 있다. 안드로이드 플랫폼과 Service 간의 상호 작용 과정에서, 특정 어플리케이션이 코드상으로는 별다른 문제 없이 작성된 경우에도, Service 가 정상 종료되지 않고 백그라운드에 남아있을 수 있다. 예를 들어 다음과 같은 상황이다.
  1. Application 이 StartService 를 호출 한다.

  2. Service 의 onCreate, onStart() 함수가 호출 되고, 특정한 작업을 수행하기 위해 백그라운드 스레드가 생성된다.

  3. 시스템이 메모리 부족으로 인해 현재 작동중인 서비스를 강제로 종료 한다.

  4. 잠시 후에, 메모리 상황이 호전되어 Service 가 재시작한다. 이 때, Service 의 onCreate 함수는 호출 되지만, onStart 는 호출 되지 않는다. (startService 는 호출 되지 않았음으로..)

 
 결국, Service 는 생성된 채로 남아있게 된다. Service 는 어떠한 일을 수행 하지도 않으며 (무슨 일을 수행해야할 지 알 수 없음으로...), 어떤 시점에 종료되어야 하는지도 알 수 없다.

 이러한 문제를 해결하기 위해 안드로이드 2.0 에서 Service 의 onStart() 는 더이상 사용되지 않는다. (이전 버전과의 호환성 문제때문에 작동 자체는 하지만...) 대신 Service.onStartCommand() 콜백이 사용된다. 이 콜백 함수는 시스템이 Service 를 좀 더 잘 관리 할 수 있도록 해주는데, 기존 API 와는 달리  onStartCommand() 는 결과값을 반환한다. 안드로이드 플랫폼은 이 결과값을 기반으로 만일 작동중인 서비스가 강제로 종료될 경우, 어떠한 일을 수행해야 하는지 판단한다.
  • START_STICKY  는 기본적으로 이전과 동일하게 작동한다. 이전과의 차이점은 다음과 같다.  기존에 프로세스가 강제 종료된 후 Service 가 재 시작 될 때, onStart() 콜백이 호출 되지 않았지만, START_STICKY 형태로 호출된 Service 는 null Intent 가 담긴 onStartCommand() 콜백 함수가 호출된다. 이 모드를 사용하는 Service 는 null Intent 로 onStartCommand() 콜백 함수가 호출되는 경우를 주의깊게 처리해야 한다. 
  • START_NOT_STICKY 모드로 시작된 Service는  안드로이드 플랫폼에 의해 프로세스가 강제로 종료되는 경우, 다시 시작되지 않고 종료된 상태로 남게된다. 이러한 방식은 특정 Intent 로 주어진 명령을 수행하는 동안에만 Service 가 실행되면 되는 경우에 적당하다 예를 들어, 매15분마다 네트워크 상태를 체크하기 위해 실행되는 Service 를 생각해 보면, 만일 이 Service 가 작업도중 강제로 종료될 경우, 이 Service 는 재시작하기 보다는 정지된 상태로 남겨두고, 15분 후에 새롭게 시작되도록 하는 것이 최선이다. 
  • START_REDELIVER_INTENT  는 START_NOT_STICKY 와 유사하다. 단, 프로세스가 강제로 종료되는 경우 (stopSelf() 가 호출 되기 전에 종료되는 경우), Intent 가 다시 전달 되어 Service 가 재시작 한다.  (단, 여러차례 시도한 후에도, 작업이 종료되지 않으면, Service 는 재시작되지 않는다.) 이 모드는 전달받은 명령을 반드시 수행해야 하는 Service 에 유용하다. 
 기존에 존재하는 어플리케이션과의 호환성을 위해서, 이전 버전을 기준으로 제작된 어플리케이션은  START_STICKY_COMPATIBILITY 모드로 작동한다.  (null intent 를 보내지 않고 기존과 동일하게 작동). 단 API 버전 5  이상을 기준으로 작성된 어플리케이션들은 기본적으로 START_STICKY 모드로 작동 하며, 개발자는 반드시 onStart() 나 onStartCommand() 가 null intent 를 가지고 호출되는 경우를 염두해 두어야 한다. 

 개발자들은 아래에 제시된 코드를 활용하여, 손쉽게 이전 버전과 새로운 버전 양쪽 모두에서 작동하는 Service 를 구현할 수 있다. 

    // This is the old onStart method that will be called on the pre-2.0
    // platform.  On 2.0 or later we override onStartCommand() so this
    // method will not be called.
    @Override
    public void onStart(Intent intent, int startId) {
        handleStart(intent, startId);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        handleStart(intent, startId);
        return START_NOT_STICKY;
    }

    void handleStart(Intent intent, int startId) {
        // do work


New "running services" user interface

 * 이 후 이어지는 내용은 새롭게 추가된 Running Service 를 확인 할 수 있는 UI 어플리케이션에 관한 내용이라 대충 대충 건너 띄도록 하겠습니다.

 안드로이드 2.0 부터는 새롭게 "Running Services" Activity 가 어플리케이션 세팅에 추가 되었다. 사용자는 목록에 표시된 Service 를 터치해서 종료할 수 있다.

 화면 하단부에는 현재 시스템의 메모리 상황에 대한 정보가 표시된다. 

  • Avail: 38MB+114MB in 25 은 현재 38MB 의 공간이 바로 사용가능하며, 114MB 의 메모리 공간은 언제든지 종료시킬 수 있는 25개의 백그라운드 프로세스에 의해 점유되고 있음을 알려준다. 
  • Other: 32MB in 3 은 현재 3개의 임의로 종료되서는 않되는 포그라운드 프로세스에 의해 32MB 의 공간이 사용되고 있음을 알려준다. 
 대부분의 사용자들에게 이 새로운 UI 는 기존의 Task Killer 어플리케이션에 비해 사용하기 편리하며, 강제로 Service 를 종료시키는 것이 아니기 때문에 문제를 일으킬 소지가 훨씬 적다. 

 개발자들에게는 자신이 작성한 어플리케이션이 잘 작동하는지 (특히 Service 관리라는 측면에서) 확인 할 수 있게 해주는 유용한 툴이 될 수있다. 또한 어플리케이션이 구동한 Service 가 사용자에 의해 어느시점에서든지 종료 할 수 있다는 점을 염두해 두어야 한다. 안드로이드의 Service 는 매우 강력한 도구이지만, 어플리케이션 개발자들이 전체 폰의 성능에 큰 악영향을 끼칠 수 있는 문제를 가장 많이 일으키는 도구이기도 한다. 





huewu 님의 강좌/학습 최신글 [더보기]


추천/비추천 클릭하면 추천받으신 분, 추천하신 분 모두에게 포인트가 지급됩니다.

어헝헝 2010-07-28 (수) 10:48
아직 초보단계에서 이 글을 보니 어지럽군요. @.@
댓글주소 추천 추천 0
huewu 2010-07-28 (수) 14:07
으음... 아무래도 개발 문서이다 글 내용이 좀 딱딱하고 지루한 경향이 있습니다. 하지만 요즘 문제가 되고 있는 이른바 좀비 어플리케이션을 방지하기 위해서라도, Service Lifecycle Changes 관련 항목은 한번 읽어보실만 합니다^^
댓글주소 추천 추천 0
프랭크샴락 2010-08-07 (토) 14:16
와...좋은글 잘 읽어 보았습니다. 감사합니다.^^
댓글주소 추천 추천 0
빠루 2010-11-15 (월) 17:00
좋은 글 잘 보고갑니다.
댓글주소 추천 추천 0
베스트드레곤 2010-11-20 (토) 18:41
좋은정보 감사합니다.
댓글주소 추천 추천 0
KingDroid 2010-11-27 (토) 21:34
감사합니다
댓글주소 추천 추천 0
닥터K 2010-12-05 (일) 05:07
잘 염두하겠습니다.
댓글주소 추천 추천 0
안드로이드진 2010-12-23 (목) 19:19

감사합니다~

댓글주소 추천 추천 0
SpeiclET 2011-01-05 (수) 20:43
잘보고 갑니다 ㅎ
댓글주소 추천 추천 0
★으랏차차★ 2012-01-03 (화) 18:36
좋은 글 잘 읽었습니다. 감사합니다.
댓글주소 추천 추천 0
봄날의곰 2012-03-16 (금) 20:08
초보 개발자입니다..서비스만들고있는데..좋은 자료 잘 보고갑니다..감사합니다..^^*..
댓글주소 추천 추천 0
   

총 게시물 15건, 최근 0 건
번호 제목 글쓴이 날짜 비추천 조회
15
Android New Gingerbread API : StrictModehttp://android-developers.blogspot.com/2010/12/new-gingerbread-api-strictmode.html[이 포스트는 어플리케이션 반응 속도에 광적으로 집착하…
huewu 12-17 0 17137
14
Android How to use Proguard in the Eclipse이글은 http://developer.android.com/guide/developing/tools/proguard.html 의 내용을 기반으로 작성되었습니다. 프로가드는 …
huewu 12-16 0 16615
13
Android 2.3 Platform Highlights For Me... 2010년 12월 7일. 드디어 말 많고 탈 많던 안드로이드 2.3 진저브레드가 공개되었습니다. 연초만 하더라도, 버전이 3.0 …
huewu 12-07 0 18978
12
Android Screen Geometry Fun[이 포스트는 Tim Bray 에 의해 작성되었습니다.]http://android-developers.blogspot.com/2010/09/screen-geometry-fun.html스마트 폰의 열풍이 채 가…
huewu 12-01 0 13217
11
<안드로이드에는 간편하고 맛있는 Toast가 UI로 제공됩니다.>Android Toast 안드로이드에서 간단한 알림 메세지등을 출력하고자 할 때 가장 손쉽게…
huewu 08-06 0 22094
10
Android Licensing Service For Android Applications원문: http://android-developers.blogspot.com/2010/07/licensing-service-for-android.html관련글: Licensing Service For Android Appli…
huewu 07-28 0 11550
9
Service API changes starting with Android 2.0원문 : http://android-developers.blogspot.com/2010/02/service-api-changes-starting-with.htm안드로이드 어플리케이션 개발에서 가장 …
huewu 07-26 0 15622
8
<안드로이드 Context 는 수수께기가 많은 클래스입니다> Android Context Story 저에게 안드로이드 Context 는 참 어려운 녀석입니다. 안드…
huewu 07-19 0 25469
7
Android Playing With ListView Choice Mode 샘플 코드: http://code.google.com/p/weathermusic/source/browse/#svn/trunk/example/choice_mode  안드로이드 GUI 개발에 있어서 가장 요…
huewu 07-15 0 29531
6
Making Sense of Multitouch 원문: http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html 어플리케이션을 개발하는데 있어서 사용자 인터페이스 부…
huewu 07-15 0 24784
5
Multitasking the Android Way [이 포스트는 Dianne Hackborn 에 의해 작성되었습니다. 그녀는 안드로이드의 개발에 매우 중요한 위치에 있는 소프트웨어 엔…
huewu 07-15 0 13001
4
On Android Compatibility 원문: http://android-developers.blogspot.com/2010/05/on-android-compatibility.html [이 포스트는  안드로이드 오픈소스, 안드로이드 호환성 프…
카이로 06-14 0 12177
3
  <안드로이드의 핵심 철학. 그것은 바로 평등>  안드로이드 플랫폼의 특징에는 여러가지가 있습니다만, 그중에서도 가장 독특한 점을…
카이로 06-14 0 14798
2
  Android App Install Location 원본:http://developer.android.com/guide/appendix/install-location.html  안드로이드 2.2 버전 업데이트에서 변경된 사항 중 가장 특이…
카이로 06-14 0 20096
1
안녕하세요. 운영자 카이로입니다. http://blog.naver.com/huewu 를 운영하고 계시는 휴님을 알고 계신지요? 정말 유용한 번역 글 및 다양한 좋은 글들을 블…
카이로 06-14 0 11476
 


Copyright ⓒ www.androidside.com. All rights reserved.
2014-08-21 ~ 2014-08-28
입장 최소 활동 포인트: 150 (미확정)
로그인해야 합니다.
공개 채팅: 평일 !(9시 ~ 17시),토,일
포인트 정책 보러가기
챗방 숨기기 |  챗방 보이기