태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

내가 누군지 말해줘! - 인텐트 필터 (Intent Filter)

2009.10.14 06:17


암시적 인텐트(Implicit Intent)를 처리하려면 인텐트 객체에 들어 있는 여러 정보를 이용해야 한다는 것을 앞에서 알아보았습니다. 인텐트 객체 내의 정보들을 통해 호출해야 할 컴포넌트의 정보를 알았으니, 그 다음엔 이 정보를 바탕으로 각 컴포넌트별로 비교를 해보며 적절한 컴포넌트를 찾아야 합니다.

이렇게 인텐트 객체 내의 여러 정보들을 바탕으로 가장 적절한 컴포넌트를 찾는 과정을 인텐트 해석(Intent Resolving)이라 합니다.  이 과정에서 인텐트 객체의 정보와 각 컴포넌트의 정보를 비교하게 되며, 이을 위해 각 컴포넌트는 자신이 받을 수 있는 인텐트의 종류를 메니페스트 파일에 정의합니다. 이를 인텐트 필터(Intent Filter)라 합니다,
 
안드로이드 시스템 내부에서는 수많은 어플리케이션들에 의해 수많은 인텐트들이 발생합니다. 이 중에서 자신에게 필요한 인텐트만을 받기 위해 인텐트 필터가 있는 것이죠.



하지만, 인텐트 필터가 없다고 해서 인텐트를 받을 수 없는 것은 아닙니다. 인텐트 필터는 인텐트 해석 과정이 필요한 암시적 인텐트(Implicit Intent)를 받을 때만 필요할 뿐, 호출 대상 컴포넌트가 명시되어있는 명시적 인텐트(Explicit Intent)는 이러한 인텐트 필터가 없어도 대상 컴포넌트를 호출할 수 있습니다.

- 어플리케이션간 경계가 없는 안드로이드

명시적 인텐트를 사용하면 굳이 인텐트 필터를 정의할 필요도 없고, 간단히 컴포넌트를 호출할 수 있는데 왜 암시적 인텐트가 있는 것일까요? 그 이유는 바로 "명시적" 인텐트의 이름에서도 알 수 있듯이, 명시적 인텐트는 호출 대상 컴포넌트의 이름을 정확히 알아야 하기 때문입니다.

안드로이드가 다른 시스템과 가장 다른 점이 바로 "어플리케이션 간에 경계가 없다"는 것입니다. 이는, 서로 다른 어플리케이션 내의 컴포넌트라 할지라도 사용자가 사용하는 입장에서 볼 때에는 마치 하나의 어플리케이션처럼 동작하는 것이죠. 

 


위의 영상에서는 바코드 스캐너와 책 관리 어플리케이션이 예로 나옵니다. 바코드 스캐너 어플리케이션은 책 관리 어플리케이션 내에 포함되어 있지 않지만, 마치 책 관리 어플리케이션의 일부인 것처럼 사용하는 것을 확인할 수 있습니다. 이런 식으로, 자신이 필요하다면 다른 사람이 만든 어플리케이션 내의 컴포넌트를 사용할 수 있으므로 개발 시간을 줄여줄 뿐 아니라, 똑같은 걸 다시 만들 필요가 없으니 효율도 증가하겠죠?

- 왜 암시적 인텐트를 사용하는가?

자, 이제 본격적인 문제는 여기서부터입니다. 자신이 만든 컴포넌트라면 컴포넌트의 이름을 정확하게 알 수 있겠지요. 하지만, 다른 사람이 만든 컴포넌트의 이름을 알기란 어렵습니다. 즉, 명시적 인텐트를 사용하여 해당 컴포넌트를 호출할 수가 없죠. 따라서 암시적 인텐트를 통해 컴포넌트를 호출하게 됩니다.

암시적 인텐트를 사용하는 이유는 이 뿐만이 아닙니다. 안드로이드가 다른 시스템과 다른 것 중 또 하나는 바로 Native 어플리케이션 (Home, Dialer 등...)까지도 사용자가 별도로 제작한 것으로 대체할 수 있다는 것입니다.

Native 어플리케이션을 호출할 때 만약 명시적 인텐트를 사용한다면 사용자가 만든 어플리케이션으로 Native 어플리케이션을 대체하는 것은 불가능하겠지요? 하지만, 암시적 인텐트를 사용하여 호출 대상 컴포넌트가 처리해야 할 작업만을 명시한다면 특정 작업의 처리를 꼭 하나의 어플리케이션만 하는 것이 아니라, 여러 가지의 어플리케이션을 통해 할 수 있게 됩니다. 마치 우리가 그림 파일을 편집할 때 포토샵을 쓰는 사람도 있고, 페인트샵을 쓰는 사람도 있는 것과 마찬가지죠.

- 인텐트 필터의 구성요소

인텐트 필터는 인텐트 객체 내의 정보들을 바탕으로 인텐트를 필터링하기에 인텐트 객체 내의 정보들을 바탕으로 자신이 받을 수 있는 정보들을 정의하며. 이 정보들 중 인텐트 필터에서 주로 필터링하는 항목은 action, data (데이터 주소 유형 및 데이터 타입), category입니다.

이러한 인텐트 필터의 내용들을 어플리케이션이 실행되기 전에 안드로이드 시스템에서 알고 있어야 다른 어플리케이션에서 해당 어플리케이션의 컴포넌트를 필요로 하는 인텐트를 발생시켜도 해당 컴포넌트를 실행시킬 수 있습니다. 때문에, 이러한 인텐트 필터의 내용들은 메니페스트 파일인 AndroidManfest.xml 파일의 각 컴포넌트 태그 내에 정의됩니다.

        <activity android:name=".LifeCycleTester"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

지금부터는 인텐트 필터 내의 각 속성들에 대해 하나씩 알아보도록 하겠습니다.

1. action (액션) 필터

인텐트 객체 내의 action을 검사하여 인텐트 필터에 정의된 액션과 일치하는지 여부를 검사합니다. 이 검사를 통과하려면 인텐트 객체 내의 액션이 인텐트 필터에 정의된 액션과 일치해야 합니다. 단, 인텐트에 액션이 아예 정의되어있지 않은 경우에는 액션 필터를 통과할 수 있습니다.


위에서 보면 인텐트 객체에 정의된 액션의 이름과 인텐트 필터에 정의된 액션의 이름이 조금 다른데, 사실 표현 방식만 다르지 결국은 똑같은 값입니다. Intent 클래스의 API를 보면, Intent 객체 내의 상수로 정의된 ACTION_VIEW 의 실제 값은 android.intent.action.VIEW 인 것을 확인할 수 있습니다.


2. category (카테고리) 필터

인텐트 객체 내의 category 항목을 검사하여 인텐트 필터에 정의된 카테고리와 일치하는지 여부를 검사합니다. 액션 검사에서는 인텐트 객체 내에 아예 액션이 정의되어있지 않은 경우 액션 검사를 통과할 수 있었던 것에 반해 카테고리 검사는 인텐트 객체에 정의된 카테고리가 인텐트 필터에 정의된 카테고리들과 일치해야 합니다.

예를 들면, 인텐트 필터에서 CATEGORY_DEFAULT와 com.androidhuman.TEST_CATEGORY가 정의되어 있을 경우 카테고리로 CATEGORY_DEFAULT를 가지는 인텐트 객체, com.androidhuman.TEST_CATEGORY를 가지는 객체, 혹은 둘 다 가지고 있는 인텐트 객체가 카테고리 검사를 통과할 수 있습니다. 하지만, CATEGORY_DEFAULT는 가지고 있는데 com.androidhuman.NEW_CATEGORY를 가지는 인텐트 객체의 경우 인텐트 필터에서 NEW_CATEGORY가 정의되어있지 않으므로 카테고리 검사를 통과할 수 없습니다.

이 때문에, 암시적 인텐트를 만들 때 카테고리를 추가하지 않을 경우 안드로이드에서 자동으로 CATEGORY_DEFAULT(android.intent.category.DEFAULT)를 추가해주게 됩니다. 때문에 카테고리를 특별히 추가해주지 않은 인텐트를 받을 수 있게 하려면 카테고리 필터에 android.intent.category.DEFAULT 를 추가해줘야 합니다. 그렇지 않으면 어떠한 암시적 인텐트도 받을 수 없게 됩니다.



3. data (데이터) 필터

인텐트 객체 내의 data 항목 및 type을 검사하여 인텐트 필터에 정의된 값과 비교하여 일치 여부를 검사합니다.
데이터 검사는 크게 데이터의 주소(URI)를 검사하는 부분과 데이터의 유형(type, MIME type)을 검사하는 부분으로 나누어집니다.

데이터의 주소를 검사하는 부분은 데이터의 주소를 세분화하여 검사할 수 있도록 되어있습니다. URI(Uniform Resource Identifier)는 다음과 같은 구조로 구성되어있습니다.

scheme://host:port/path

만약, http://google.com 을 각 요소별로 나누어본다면 schemehttp, host google.com 이 되겠죠? 이와 마찬가지로 안드로이드 시스템에서 사용하는 주소들도 각각의 요소들로 나눌 수 있습니다.
예를 들어 content://com.androidhuman.provider.SimpleMemo/memos/1 같은 주소의 경우 schemecontent, hostcom.androidhuman.provider.SimpleMemo, pathmemos/1 이 되겠지요??
데이터의 유형을 필터링하는 것은 type(mimeType)을 이용합니다. 보통 아래와 같이 정의됩니다.

<data android:mimeType = "video/mpeg" android:scheme = "http">
<data android:mimeType = "audio/*" android:scheme = "http">

mimeType은 위와 같은 형식으로 정의되며, 큰 범주/큰 범주의 하위 범주 형식으로 정의됩니다. (video/mpeg의 경우 큰 범주가 video, video의 하위 범주가 mpeg) 하위 범주에는 와일드카드 문자(*) 를 사용하여 해당 범주 내의 모든 형식을 허용할 수도 있습니다.

이런 방식으로 첫번째 <data> 필터를 해석하면 "http 스키마를 가진 mpeg 형식의 비디오 데이터"를 가진 인텐트를 허용하는 것임을 알 수 있고, 두번째 필터는 "http 스키마를 가진 모든 오디오 데이터"를 가진 인텐트를 허용하는 것임을 알 수 있습니다.


지금까지 인텐트 객체 및 인텐트 필터의 각 필터들 및 인텐트 필터의 통과 조건들에 대해 알아보았습니다. 다음 강좌에서는 NotePad 예제에 정의되어있는 인텐트 필터들을 보고 해석하면서 오늘 배운 내용들을 다시 한번 정리해보도록 하겠습니다. :)
저작자 표시 비영리 변경 금지
신고

커니 어플리케이션 구성/인텐트(Intent) , , , , , , , ,

  1. Blog Icon
    꾸니

    허허~ 기가막히네요~
    인터넷 검색하고 책 욜라 봐도 이해가 잘 안갔던걸.. 이 사이트에서 한번에 이해했습니다.
    정말 잘 봤습니다~ ^0^/ 속이 다 후련하네~

    다른부분도 다 읽어봐야겠네요 ^^

  2. Blog Icon
    띠용

    쉽게 잘 정리해주셨 네요..
    잘 보고 갑니다.. 다음 과정도 봐야지...

  3. Blog Icon
    세오쿠

    정리된 내용 잘 보았습니다.

    내용 중 궁금한 것이 있어서 한 가지 여쭙니다.

    Intent는 category를 지정하지 않으면 CATEGORY_DEFAULT를 추가하며 암시적 Intent의 경우

    Intent-filter에서 해당 category가 추가되어 있지 않으면 Intent-filter를 통과 할 수 없다고 보았는데요.

    startActivity()로 암시적 Intent 사용시는 category를 필요로 하나, sendBroadcast의 경우는

    Intent-filter에 category를 추가하지 않아도 전달이 되더군요.

    sendBroadcast의 경우엔 category를 추가하지 않아도 intent-filter를 통과 할 수 있는 이유가

    궁금합니다.

  4. Blog Icon
    들개

    글게요. 저도 궁금해서 검색해봤는데 관련 이야기가 없더군요...

  5. CATEGORY_DEFAULT 카테고리가 추가되는 건 액티비티를 호출하는 암시적 인텐트에만 해당됩니다.때문에 sendBroadcast()를 사용하여 브로드캐스트 메시지를 보낼 때나 startService()를 사용하여 서비스를 호출할 때는 인텐트 필터에 CATEGORy_DEFAULT가 없어도 됩니다.

  6. Blog Icon
    세오쿠

    답변 잘 받았습니다.

    이제 이해가 가네요.

    답변 감사합니다. 좋은 하루 되세요.

  7. Blog Icon
    만사

    잘봤습니다. 궁금한 점이 있는데 첫번재 표에서 액션에 대한 인텐트 필터가 아무것도 지정안되있으면 어더한 액션도 허용한다라는 내용인가요? 만약 그러하다면 표에서 없음 과 어떠한 액션이든 상관없음이 서로 바껴야 하는 건가요?
    궁금해서 질문합니다.

  8. 인텐트 필터에 지정된 액션과는 상관없이 인텐트 자체에 아무 액션이 지정되어 있지 않다면 인텐트 필터를 통과할 수 있다는 것을 의미합니다. :)

  9. Blog Icon
    만사

    답변 감사합니다. 실제로 테스트 해보니 말씀하신대로 intent에 액션을 지정안해주니. 어떠한filter에도 pass하는 듯 합니다. professional android2 책을 보고 있는데, 거기서는 '인텐트 필터에 액션이 정해져있지않으면 액션일치가 된다'라고 적혀져있었습니다. 잘못 적혀있는듯하네요. 커니 님이 말씀하신게 맞는거 같아요 좋은 정보 감사합니다.! ^^

  10. Blog Icon
    가람

    좋은 정보 갑사 합니다.
    이제 막 시작 했는데
    공부하다 궁금한게 있으면 물어 볼께요 ^^

  11. Blog Icon
    학생

    좋은 정보 감사합니다 ^ ㅁ ^

  12. Blog Icon
    OTL

    10번째 줄에 필요햔(X) 필요한(O), 인터넷도 잘보고있고 책도 잘 보고있습니다.
    그나자나 인텐트 필터.. 이해가 너무안되네요 ㄱ-

  13. 수정했습니다 :)
    인텐트랑 인텐트 필터가 처음엔 좀 어려워요~ 그래도 안드로이드쪽에선 핵심 개념이니까 한번 확실히 알아두는게 좋아요 ㅎㅎ

  14. Blog Icon
    지나가던이

    안드로이드에서 자동으로 CATEGORY_DEFAULT(android.intent.category.DEFAULT)를 추가해주게 됩니다. 때문에 카테고리를 특별히 추가해주지 않은 인텐트를 받을 수 있게 하려면 카테고리 필터에 android.intent.category.DEFAULT 를 추가해줘야 합니다. 그렇지 않으면 어떠한 암시적 인텐트도 받을 수 없게 됩니다.
    < 여기서 자동으로 추가해 주는데 왜 추가를 꼭 해줘야 하는 건가요? 이해할 수가 없네요... ㅎ

  15. 인텐트를 날릴(?)때 (Intent 객체를 만들 때) 카테고리를 지정하지 않으면 이 인텐트 객체에 자동으로 Intent.CATEGORY_DEFAULT를 추가해주게 됩니다.

    그런데, 매니페스트의 인텐트 필터에 액션만 선언하고 category를 선언해주지 않으면 위에서 날리는 인텐트를 수신하지 못하게 됩니다. 때문에 인텐트 필터에 추가로 카테고리 필터를 선언하는 것입니다.

  16. 정말 훌륭하게 정리 잘해주셨습니다.
    내가 아는 지식을 남이 쉽게 알수 있게 하는것이야 말로 가장 훌륭한 능력처럼 보이네요.
    잘 읽고 갑니다.

  17. Blog Icon

    비밀댓글입니다

  18. 네 괜찮습니다!

  19. Blog Icon
    MRJACK

    와우 쉬운 설명 감사합니다 최고네요 ㅡ,.ㅡ 저도 이런 강좌 써보고 싶음

  20. Blog Icon

    비밀댓글입니다

  21. Blog Icon

    비밀댓글입니다

  22. Blog Icon

    비밀댓글입니다

  23. Blog Icon
    초보개발

    책보면서 공부하고 있는데, 책을 잘 못 선택했는지 intent부분은 그냥 넘어가더라구요.
    급히 개발할 게 있어서 구글링 하다가 들렸는데 너무 좋은 정보가 많네요. 감사합니다.