안드로이드 서비스 상태별 바인딩 결과 테스트

안드로이드에서 작업 시간이 오래 걸리는 작업은 서비스를 사용하도록 권장한다. 그리고, 다른 컴포넌트는 이 서비스와 데이터를 지속적으로 주고받기 위해 바인딩 할 수 있다.

서비스 바인딩에 대해서는 이미 많은 글이 있으므로 생략하고, 여기서는 서비스의 상태(서비스의 위치, 이름, 반환 값 등)에 따라 메소드들이 호출되는지 여부와 어떤 값을 반환하거나 전달 받는지 정리한다. 참고로, 테스트는 N O/S에서 진행했다.

각 항목을 간략히 설명하면,

  • 서비스 위치 : 서비스에 바인딩하는 컴포넌트와 서비스가 같은 프로세스 안에 있는지 여부
  • 서비스 존재 여부 : 실제 서비스가 존재하는지 여부
  • 서비스 활성화 여부 : 서비스는 존재하는데, 그 서비스가 활성화(enabled)되었는지 여부
  • 서비스 내 onBind()의 반환값 : 서비스 내의 onBind() 메소드에서 반환하는 객체
  • 액티비티 내 bindService 반환 값 : bindService() 메소드의 반환 값
  • 서비스 내 onBind() 호출 : 서비스 내의 onBind() 메소드 호출 여부
  • 액티비티 내 onServiceConnected() 호출 : 액티비티에서 서비스 바인딩 시도 후, onServiceConnected() 가 호출되는 지 여부
  • 액티비티 내 onServiceConnected()의 IBinder 객체 : onServiceConnected() 메소드가 호출 된 경우, 파라미터로 전달받은 IBinder의 객체 여부
  • 서비스 내 onUnbind() 호출 : 액티비티에서 서비스 언바이딩 시도 후, 서비스 내의 onUnbind() 메소드가 호출되는지 여부
  • 액티비티 내 onServiceDisconnected() 호출 : 액티비티에서 서비스 언바인딩 시도 후, 액티비티 내의 onServiceDisconnected() 메소드가 ‘즉시’ 호출되는지 여부

이다. 위 5가지 테스트 중에 T3가 특이하다. 액티비티가 서비스 바인딩 시도 시, 서비스의 onBind() 메소드에서 null을 반환한다면 bindService() 의 반환으로 true를 건넨 후 후로 더이상 진행되지 않는다. 그러므로 서비스 바인딩을 시도한 컴포넌트의 입장에서는 onBind()에서 null을 반환한 경우, 어떤 문제가 발생했는지 알 수 없다.

이 문제는 아래와 같이 구현되었다면 더 좋을 것 같다.

  • bindService() 호출 시, false 반환
  • onServiceConnected()가 호출되고, IBinder 가 null로 반환

그래야, 서비스 바인딩을 시도했던 액티비티가 예외처리를 할 수 있었을 텐데 말이다.

그 밖에

실제로는 onBind() 메소드에서 null을 반환하는 코드가 IntentService 내에 쓰이고 있다.  서비스의 구동 방식을 모르고 바인딩 시도하는 경우가 없으리라는 판단한 것으로 보인다.

참조

Android API 18에서 startForeground()

Android API 17까지는 서비스가 시스템에 의해 강제종료 되는 것을 막기 위해서 서비스 시작 부분에 startForeground()를 호출했다. 이번 Android API 18에서도 여전히 사용할 수 있지만 notification bar에 안내가 강제로 뜬다.

시스템 앱(/system/app, /system/framework, /vender 폴더에 있는 앱)의 경우에는 기존과 같이 notification bar에 안내가 뜨지 않고 죽지않는 서비스를 만드는 방법이 있다. Androidmanifest.xml 파일의 <Application 선언 부분에 android:persistent=”true” 를 선언하는 것이다. 시스템 앱의 경우, 저 파라미터를 넣어주면 시스템에 의해 강제 종료 되지 않는다.

하지만, 다운로드 받은 앱은 조용히 안죽는 서비스를 만드는 방법이 없다. 원래 startForeground()함수를 이용하면 notification bar에 안내가 되어야 하는데 이전까지는 버그(추측이지만)로 인해 뜨지 않는 것이었고, 18부터는 title과 content를 넣지 않으면 기본 정보를 이용해서라도 notification bar에 현재 포그라운드로 실행되고 있는 서비스 정보가 노출되도록 수정되었다.