출처
[Android] TaskKiller에 죽지 않는 서비스(Service) 만들기 1
이전 포스팅까지 안드로이드 잠금화면 만들기의 기초에 대해 알아보았습니다.
이번에는 잠금화면의 최대의 적 .. TaskKiller !! 정말 무서운 놈이죠 ㅠ 클릭 한방으로 우리가 돌리는 서비스를 죽여버립니다ㅠㅠ
물론 Service의 onStartCommand()메소드의 리턴값을 START_REDELIVER_INTENT 또는 START_STICKY 로 하면 메모리의 여유가 생겼을 때 다시 서비스가
살아난다고 되어있죠! 근데 막상 해보면 매우 답답하게 느릿느릿 살아납니다. 어쩔땐 안살아나기도...ㅜ! 그럼 어떻게 해야할까요 ~
TaskKiller에 죽지 않는 서비스 만드는 방법은 대체로 두가지 입니다. 첫 번째는 죽어도 다시 살려내는 방법이고, 두 번째는 첨부터 잘 안죽게 하는 방법입니다.
이번 포스팅에서는 첫번째 방법인 AlarmManager를 이용해서 되살아나는 서비스를 만드는 방법에대해 알아보겠습니다.
AlarmManager을 통해서 되살아나는 서비스 만드는 방법
public void registerRestartAlarm(boolean isOn){
Intent intent = new Intent(ScreenService.this, RestartReceiver.class);
intent.setAction(RestartReceiver.ACTION_RESTART_SERVICE);
PendingIntent sender = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
if(isOn){
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 1000, 10000, sender);
}else{
am.cancel(sender);
}
}
이 코드를 지난 시간에 만든 ScreenService에 넣어줍니다.
그리고 서비스가 시작될 때 registerRestartAlarm(true)를 호출하고 서비스가 종료될 때 registerRestartAlarm(false)를 호출해주면 됩니다.
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 1000, 10000, sender); 이부분을 살펴봅시다.
첫번째 매개변수에는 기준 시간이 들어갑니다. ElAPSED_REALTIME_WAKEUP은 현재 시작되는 시간을 0으로 하는 상대적인 시간입니다.
바로 지금! 이라고 하는거죠. ElAPSED_REALTIME 과 다른점은 시스템이 휴면상태에 들어가면 깨워라! 가 추가됩니다.
절대시간을 사용하고 싶다면 RTC 또는 RTC_WAKEUP을 사용하면 됩니다. 두번째 매개변수는 언제 처음 시작할건가 입니다.
SystemClock.elapsedRealtime() + 1000 이라는 것은 지금부터 1초(1000ms)후라는 의미입니다. 세번째 매개변수는 반복되는 시간 간격입니다.
10000ms마다 이므로 10초에 한번씩 입니다.
마지막 매개변수는 알람이 전해줄 PendingIntent로 위에서 작성한 코드대로면 RestartReceiver에 ACTION_RESTART_SERVICE를 전달하겠습니다.
그리고 RestartReceiver.java 파일을 다음과 같이 작성합니다.
public class RestartReceiver extends BroadcastReceiver{
static public final String ACTION_RESTART_SERVICE = "RestartReceiver.restart"; // 값은 맘대로
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(ACTION_RESTART_SERVICE)){
Intent i = new Intent(context, ScreenService.class);
context.startService(i);
}
}
}
그리고 Manifest.xml 파일에도 RestartReceiver를 추가해야겠죠!
<receiver
android:name=".RestartReceiver"
android:process=".remote" >
<intent-filter>
<action android:name="RestartReceiver.restart" />
</intent-filter>
</receiver>
android:process=".remote" 이부분은 시스템의 Alarm을 받기위해서 추가됩니다.
즉, 요약하자면 1초 후부터 10초에 한번씩 RestartReceiver를 작동시키는 알람을 등록하게 됩니다.
이 알람은 OS단에서 관리되기 때문에 TaskKiller에 영향을 받지 않습니다. RestartReceiver는 알람을 받고 ScreenService를 다시 실행시키게 되는 형식입니다.
만약 TaskKiller에 의해 서비스가 죽더라도 10초안에 알람을 통해서 살아나게 되는 것이지요.
하지만! 10초에 한번씩 알람을 통해 찌른다는 것이 .. 굉장히 비효율적으로 보이는 것은 사실입니다.
따라서 저도 처음에는 이 방법을 사용하다가 현재는 다음포스팅에 이어질 두번째 방법을 메인으로 사용하고,
이 방식은 30분에 한 번만 알람이 오도록 해두었습니다. 일종의 보험 느낌이죠 ㅋ
[Android] TaskKiller에 죽지 않는 서비스(Service) 만들기 2
이번 시간에는 아주 유용하게 쓸 수 있는 죽지 않는 서비스를 만드는 방법에 대해서 알아보겠습니다. 이 방법은 음악재생, 파일다운로드 등을 할 때와 같은 방법으로 넘 강력해서 강력한 태스크 킬러에서도 죽지 않죠 ~ ! 그건 바로 Foreground Service로 실행하는 것입니당 !! 다들 경험해보셔서 아시겠지만 음악을 들을 때는 아무리 태스크 킬러를 눌러도 음악이 멈추지 않습니다. 그 방식이 바로 Foreground Service이기 때문이죠. 다만 한가지 ! 그런 아이들의 특징이 있습니다. 그건 바로 Notification! 음악이 재생될 때는 항상 Notification 상태바에 음악이 재생되고 있슴. 이런 메세지 또는 음악 컨트롤러 등이 등장하죠.
Foreground Service를 통해 죽지 않는 서비스 만들기
startForeground(int id, Notification notification)
뚜둥.. 단지 저 메소드를 앞에서 만든 ScreenService의 onStartCommand()안의 어딘가에 넣어주면 됩니다. 넘.. 간단 합니다 ;; 여기서 int id 는 Notification의 id를 의미하며 Notification notification 는 서비스가 foreground로 실행되는 동안 나타날 Notification입니다. Notification을 띄우는 방법에 대해서는 다음에 알아보기로 하고~ 일단은 간단하게 띄워 보겠습니다.
Notification notification = new Notification(R.drawable.ic_launcher, "서비스 실행됨", System.currentTimeMillis());
notification.setLatestEventInfo(getApplicationContext(), "Screen Service", "Foreground로 실행됨", null);
startForeground(1, notification);
이렇게 하면 다음과 같이 나타납니다. 아이콘은 제맘대로 넣었습니다 ㅋㅋ
이렇게 나타나고 TaskKiller에 거의 죽지 않고 계속 백그라운드에 살아 있는 서비스가 됩니다.
실제로 제가 만든 잠금화면은 죽은 걸 한 번도 보지 못했습니다.
※ 추가 ! Foreground Service 에서 Notification 없애는 방법!!!!
제가 잠금화면을 개발할 때 가장 골머리 썩었던 부분이 바로 이부분입니다. 위에서 처럼 foreground service로 Notification에 나타내면 죽지 않습니다..
근데 문제는 !! Notification에 나타내기 싫었던거죠 .. ㅠ 음악 플레이어도 아니고, 파일 다운로드도 아니고 굳이 보여줄 이유가 없는 서비스이기 때문이죠 !
그런데 구글을 아무리 찾아도 어떻게 하는지 안나오더군요 ㅠ 아아 으아파나나마ㅏㅏ파ㅏㅣㅣㅣ ㅜㅜㅜㅜ 이걸 어쩐다 .. 멘붕중에!
그러다 우연히 .. Foreground Service에서 Notification을 없애는 방법에대해 알아냈습니다 ㅎㅎ 바로 다음과 같이 하면 됩니다!
startForeground(1, new Notification());
아주 간단하고 황당하기 그지 없죠 .. ㅋㅋ
굳이 Notification에 설정값을 주지 않고 걍 Notification 객체만 넣었더니 다음과 같이 아무것도 나타나지 않았습니다 ! 대박 . .
그런데 !! 최근에 또 다른 문제를 직면했죠 .. 안드로이드 4.3버전(API 18)부터는 Foreground Service를 돌리면 Notification이 무조건 등록되더라고요 ㅠ
그래서 저는 어쩔 수 없이 버전체크해서 4.3 이상에서는 Notification을 커스터마이징해서 띄우고 그 이하에서는 안띄우는 방식을 사용합니다 ㅋ
그래도 엄청 쓸모잇죠 ! 감명 깊게 보셨다면 추천 고고
네~ 이것으로 죽지 않는 서비스 만들기도 끝이 났네요 ㅋ 짞짞짞 ! 이정도면 뭐 거의 아름다운 잠금화면이라고 할 수 있겠습니다 ㅋㅋ
'IT_Programming > Android_Java' 카테고리의 다른 글
[Android] 앱 설치, 삭제, 업데이트 시 서비스(Service) 실행하기 (0) | 2013.11.08 |
---|---|
[펌] Android AsyncTaskLoader에 대하여 (0) | 2013.11.04 |
Activity 생성시에 사용되는 Intent Flag 정리 (0) | 2013.10.18 |
[안드로이드] 동영상 재생시 처리 이슈들 / 기본 플레이어로 연속재생 만들기 (0) | 2013.08.31 |
안드로이드 태스크 스택 확인하기 (0) | 2013.08.19 |