컴퓨터 공학

[Android] 좀비 서비스(zombie service) 구현

bitcodic 2019. 1. 24. 20:35

잠금화면 관련 앱을 개발 중인데, 앱을 킬하면 죽어버리는 경우가 발생해서 하루종일 고생했다..


이유는 안드로이드 오레오 버전부터 백그라운드에서 Service를 실행하기가 까다롭게 변경됐기 때문이다.


--------------------------------------------------------------------------------

백그라운드 서비스 제한: 앱이 유휴 상태인 경우 백그라운드 서비스의 사용이 제한됩니다. 이 기능은 사용자에게 잘 보이는 포그라운드 서비스에는 적용되지 않습니다.


* 참고 https://developer.android.com/about/versions/oreo/background?hl=ko


--------------------------------------------------------------------------------

기본적으로 앱을 백그라운드에서 실행하는 방식은 다음과 같다.

앱을 정상적으로 종료하는 경우 > 뒤로가기/나가기 등으로
앱을 비정상적으로 종료하는 경우 > Task Kill(작업 관리자) , 핸드폰 강제로 끄기 .
.

전자의 경우는 이전처럼 Service로 구현해서 문제될 게 없었으나, 문제는 후자였다.

프로세스를 강제 종료하면, 동반된 Service도 죽어버렸다.

두 경우를 동시에 해결하는 방법은 Service를 foreground로 만들면 되는건데 오레오(또레오..) 버젼부터 foreground를 활성화시킬 경우 유저의 Notification에 지울수 없는 알림을 준다.

찾아보니 똑같은 Notification id를 가진 놈을 만들어서 지우면 된다는데 난 안된다.. (아마 예전 글이라, 안드로이드 자체에서 수정된건지도..?)

이것저것 뒤지다보니 내린 결론은, Service를 재귀적으로 호출하는 것이었다.

Service의 onDestory 함수는 Task kill을 하면 자동으로 호출된다( 문제는 이게 언제 나타날지 모름.. 1분이 걸릴지 10초가 걸릴지 ).

이 함수 내부에 Service를 시작하는 놈을 다시 둔다. 단 오레오 이상인지 확인해서, 오레오 상위 버전이면 Foreground로 잠깐 만들어주고 그 사이에 Service를 실행시켜준다. 이렇게 하는 이유는 위에 언급했듯이 백그라운드에서 Service를 실행할 수 없기 때문..

잠깐 Foreground로 만들어서 Notification도 딱히 안뜨는 것 같다.

스택오버플로우랑 다 뒤져봤는데 아마 지금은 이게 제일 좋은 방식인 것 같다.