posted by By훈트 2010.08.17 17:01


<Intent 의 변신. PendingIntent 와 IntentSender>

 안드로이드 인텐트 관련해서, 두 가지 신기한 클래스가 제공됩니다. 이름만 들어서는 그 쓸모가 무엇인지 애매한, PendingIntent 와 IntentSender 가 바로 그 주인공입니다. 개발자 사이트에 서술된 내용을 살펴보아도 두 가지가 하는일이 정확히 무엇인지, 그리고 특히, 둘 사이의 차이점이 무엇인지 좀 헷갈립니다. 두 가지 클래스는 어떤 역할을 수행하고, 어떤 차이점이 있으며, 안드로이드 어플리케이션을 개발할 때, 어떻게 유용하게 사용될 수 있는지 간단하게 정리해 보았습니다. 


1.PendingIntent

 PendingIntent 은 비교적 이해하기 쉽습니다. 커뮤니케이션에는 세 가지 기본 요소가 있습니다. 메세지, 송신자, 수신자. 인텐트는 메세지 입니다. 수신자는 해당 인텐트를 수신하기 위한 인텐트 필터를 갖고 있는 컴포넌트 입니다. 송신자는 인텐트를 보내기 위한 API (startActivity/startService 등)를 호출한 컴포넌트입니다. 


<부디 나쁜데 쓰지 말고 내가 시킨것만 잘 하시오...>

 PendingIntent 는 인텐트를 전송하고자 하는 '송신자'가 인텐트를 하나 생성한 후, 별 도의 컴포넌트에게 '이 인텐트를 나중에 나 대신 보내 주렴.' 하고 전달하고자 할 때 사용되는 클래스입니다. 즉, 내가 친구에게 은행 통장에서 돈을 대신 뽑아달라고 부탁하며, 뽑을 돈의 액수를 알려주고 (인텐트), 내 카드를 빌려주는 것과 비슷한 개념이라고 생각 할 수 있습니다. 당연히, PendingIntent 를 사용할 때는 내가 맡긴 카드가 악용되지 않도록, '권한' 문제에 관해서 신경을 기울일 필요가 있으며, 이와 동시에 안드로이드 플랫폼 상에서도 PendingIntent 의 권한 문제를 제어할 수 있는 API는 물론이고, 다양한 FLAG를 제공해 주고 있습니다. 

int FLAG_CANCEL_CURRENT 이전에 생성한 PendingIntent 는 취소하고, 새롭게 하나를 만듭니다. (친구에게 예전에 빌려준 카드를 정지 시키고 새롭게 하나 신청합니다.)
int FLAG_NO_CREATE 현재 생성된 PendingIntent 를 반환 합니다. (친구 보고 내가 빌려준 카드를 당장 가져와 보라고 요청합니다. 이 후에, 해당 카드를 회수 할 수도 있습니다.)
int FLAG_ONE_SHOT 이 플래그를 이용해 생성된 PendingIntent 는 단 한번 밖에 사용될 수 없습니다. (일회용 카드)
int FLAG_UPDATE_CURRENT 만일 이미 생성된 PendingIntent 가 존재 한다면, 해당 Intent 의 내용을 변경합니다. (친구에게 전화해서, 인출할 돈의 액수를 다시 알려줍니다.)

 따라서, 저는 의미적으로 'PendingIntent' 를 '위임된 인텐트' 라고 해석할 수 있지 않을까 생각합니다.  PendingIntent 는 여러가지로 유용하게 사용될 수 있는데(여러가지 이유로 특정 패키지만 사용가능한 컴포넌트를 다른 컴포넌트와 상호 작용시킬 필요가 있는 경우 등....)그 중에서도, 안드로이드 화면 상단에 위치한 'Notification Bar' 와 상호 작용하는 어플리케이션을 작성할 때 널리 사용됩니다.

 예를 들어, 인터넷 상에서 음악을 다운로드 받는 어플리케이션이 있습니다. 음악 다운로드가 진행 중일 때, 'Notification Bar' 에 진척 상황이 나타나도록 구현하였습니다. 그리고 다운로드가 완료된 후에 사용자가 해당 알림 정보를 클릭하면, 다운로드 완료된 음악이 재생됩니다. 얼핏 생각해보면 'NotificationBar' 가 특정 아이콘이 클릭되었을 때, 어떻게 알고 음악 재생 Activity 를 띄우는지 신기하게 여겨질 수도 있습니다. 이 과정은 우리가 'Notification Manager' 에게 특정 아이콘을 등록함과 동시에 해당 아이콘이 클릭되는 순간에 전달되어야 PendingIntent 를 넘겨 주기 때문에 가능합니다. 

public void setLatestEventInfo (Context context, CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent)


 위와 같이, Notification 클래스에는 해당 Notification 이 수행할 PendingIntent 값을 설정할 수 있도록 되어 있습니다. 즉, PendingIntent 를 잘 사용하면, 다른 컴포넌트들과 상호 작용할 때, 실재로 수행할 일 자체를 PendingIntent 를 통해 추상화 할 수 있음으로(음악을 재생해라... 라는 구체적인 명령 대신, 전달받은 PendingIntent 를 수행하라 식으로...), 보다 더 확장성있는 어플리케이션 컴포넌트를 구성할 수 있습니다.

2.IntentSender
 IntentSender 는 좀 애매합니다. 무엇보다도 IntentSender 가 사용되는 꼭 맞는 샘플 코드를 찾기가 어렵더군요. IntentSender 를 생성하는 방법도 조금 색다른데, PendingIntent 를 우선 생성한 뒤, getIntentSender() API 를 호출해야합니다. 처음에는 IntentSender 는 좀 더 추상화된 PendingIntent 가 아닐까 생각했습니다. (두 클래스 간의 직접적인 상속관계가 있는 것은 아니지만...)

 하지만, 여러가지 자료를 좀 뒤져보고 (내용은 거의 없지만...) 결정적으로 안드로이드 프레임워크 소스를 살펴본 결과 허무한 결론을 내리고 말았습니다. IntentSender 는 PendingIntent 의 쌍둥이 클래스 입니다. 말하자면, PendingIntent 에 비하면 조금 못난... 쌍둥이 동생이라고 할 수 있습니다. 위임 받은 인텐트를 전달 할 수 있다는 점에서는 PendingIntent 와 정확하게 동일하지만, PendingIntent 와 비교하면 사용하기가 좀 어렵고 결정적으로 '권한' 을 관리하기 위한 API 를 제공해 주지도 않습니다. 

<멸종 위기 클래스... IntentSender. 다음 버전에는 없어지지 않을까요?>

 이 녀석 도데체 어디에 쓰이는 걸까요? 결론은 쓰이는 곳이 없다;;; 입니다. 안드로이드 풀소스를 뒤져봐도 사용되는 곳은 전무합니다. 심지어 IntentSenderTest 에서도 사용되는 것은 PendingIntent 뿐입니다. 혹시라도 저처럼 IntentSender 가 뭐에 쓰이는 물건인고... 하고 궁금해 하시는 분이 있다면, 아 그 못난 PendingIntent 쌍둥이 동생? 정도로 가볍게 넘어가셔도 좋을 듯 하네요.



신고