Sticky intent 는 말 그대로 끈적끈적한 intent 를 말합니다. ^^;
끈적끈적해서 자신의 역할을 수행한 뒤에도 메모리에 딱 달라붙어서 사라지지 않고 남아있는 것이죠.
보통의 broadcast 된 intent는 자신과 관련된 모든 Broadcast receiver 를 거치고 나면 임무 완료되어 ‘즐거운 퇴근길에 올라’ 메모리 상에서 제거됩니다. 하지만 Sticky intent는 임무 완료 후에도 메모리에 남아 있는다는 사실! (정확하진 않지만 해당 event에 대한 다음 broadcast 가 있을 때까지 남아 있는 것 같습니다)
그럼 이 sticky intent를 어디에 사용할까요?
안드로이드에서 Broadcast receiver 는 두 가지 방법을 통하여 등록할 수 있습니다. 정적으로 AndroidManifest.xml 에 태그를 이용하여 등록하는 방법 과 동적으로 Context.registerReceiver() method를 이용하는 방법.
정적으로 등록하는 경우에는 Broadcast receiver 를 등록한 app의 실행 여부와 관계없이 관련 Broadcast intent 가 있으면 등록한 Broadcast receiver 의 onReceive() method가 호출됩니다. 무의미한 상황에서 CPU와 배터리를 사용하는 셈이 될 수도 있는 것인데요. 만약 우리가 작성한 app 이 실행 중인 상황에서만 Broadcast receiver 가 동작하기를 원한다면 정적인 등록 방법은 알맞지 않겠죠.
그래서 아래와 같이 동적으로 등록하는 방법을 사용할 수 있겠습니다.
registerReceiver(new BroadcastReceiver(){
@Override
public void onReceive(Context arg0, Intent arg1){
//TODO
}
}, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
짐작하시겠지만, 동적으로 등록하는 경우엔 당연히 Broadcast receiver 를 등록한 이후에 발생하는 intent 만을 수신하게 됩니다. 그런데 여기서 문제가 발생합니다.
예를 들어, Status Bar 에 배터리의 상태를 표현하려고 동적으로 Broadcast receiver 를 등록했는데, 이미 해당 intent (Intent.ACTION_BATTERY_CHANGED 를 action으로 갖는 intent)가 broadcast 된 후라면 그 Broadcast receiver 는 동작하지 않게 됩니다. 다음 broadcast 가 있을 때까지 말이죠. 따라서 intent 가 아닌 다른 방법으로 배터리 상태를 확인하는 코드를 추가해야 할지도 모릅니다.
하지만 편리하게도 안드로이드에서는 위와 같은 상황이 일어나지 않습니다. 배터리의 상태를 알리는 intent 는 Sticky intent 이기 때문이죠. 다시 말해 이 intent는 자신의 임무를 완료한 후에도 메모리에 남아 있다가 자신과 관련된 Broadcast receiver 가 등록되면 해당 receiver에 바로 전달되는 것입니다.
참고로 안드로이드 시스템에서 broadcast 하는 Sticky intent는 아래와 같습니다.
1) 배터리 관련 : Intent.ACTION_BATTERY_CHANGED
2) 저장소 관련 : Intent. ACTION_DEVICE_STORAGE_LOW
3) Docking 관련 : Intent. ACTION_DOCK_EVENT
4) Network 관련 : ConnectivityManager.CONNECTIVITY_ACTION