본문 바로가기

Android 공부

18. 안드로이드 Intent

Intent 는 메시징 객체로 안드로이드 개발을 하면서 startActivity( ) 메서드를 이용해 페이지를 이동하는 등의 작업을 할 때 사용했다. 하짐나 제대로 공부해 본 적은 없어서 intent 에 대해 공부했는데, 생각보다 알아야 하는 요소가 많았고 이제야 이해되는 부분도 많았다. 

 


 

Intent는 두 가지 유형으로 나눌 수 있다. 

 

1. 명시적 Intent

이름에서도 알 수 있듯이 Intent를 명시한다고 생각하면 된다. 코드 상에서 아래와 같이 요청한다면, 명시적 Intent 를 사용한 것이다. 

 

val downloadIntent = Intent(this, DownloadService::class.java).apply {
    data = Uri.parse(fileUrl)
}
startService(downloadIntent)

 

인텐트 안에 정확한 클래스의 이름을 넣어줘야 한다. 위 예시에서는 "DownloadService" 에 해당한다. Intent 를 단순하게 앱 안에서 다른 컴포넌트로 이동하는데 사용하는 객체라고 생각한다면 당연하다고 여기겠지만, Intent는 앱 안에서 뿐만 아니라 A 앱에서 B 앱을 요청할 때 역시 사용되는 객체이기 떄문에 어플 안에서 사용되는 경우에는 주로 명시적 Intent를 사용한다. 이때 요청하는 클래스가 어떤 Intent filter를 선언했는지는 신경 쓸 필요가 없다. Intent filter에 대해서는 뒤에 자세히 설명하겠다. 

 

 

 

2. 암시적 Intent

특정 구성요소의 이름을 정확하게 명시하지는 않지만 수행할 작업을 선언하여 다른 구성요소가 이를 처리할 수 있도록 하는 경우이다. 암시적 인텐트는 startActivity( ) 로 전송한 인텐트를 처리할 앱이 해당 기기에 전혀 없을 수 있기 때문에 null 체크를 하고 사용하는 것이 안전하다.

 

// Create the text message with a string
val sendIntent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_TEXT, textMessage)
    type = "text/plain"
}

// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(packageManager) != null) {
    startActivity(sendIntent)
}

 

암시적 인텐트를 사용하면 android 시스템에서 시작할 적절한 구성요소를 찾게 되는데, 이때 Intent filter 라는 개념이 다시 등장한다. 

 

 

 

 

 

Intent filter 란 무엇일까?

 

 

앱의 manifest filter 에 들어있는 표현으로, 해당 구성요소가 수신하고자 하는 Intent 의 유형을 나타낸다. 즉, Intent filter 는 Intent 를 필터링해서 자신이 현재 필요한 인텐트를 골라 받기 위해 사용하는 것으로 가장 적절한 컴포넌트를 받기 위해 사용하는 것이라 이해하면 된다. 더 직관적으로 예시를 들어 설명해보겠다. 

 

- A 라는 어플에서 카메라를 사용할 수 있는 컴포넌트에  Intent filter 를 선언하고 B라는 어플에서 카메라를 사용할 수 있는 Intent 를 요청하면  A 어플의 해당 컴포넌트는 B 어플에서 실행되거나, 사용자가 선택할 수 있는 목록에 들어가게 될 것이다. 

- 어플을 키자마자 실행될 activity 를 Intent filter 를 통해서 선언 가능하다. 

 

다음과 같은 상황이 벌어지는 이유는, 암시적 인텐트를 사용하면 인텐트의 내용을 다른 앱의 manifest 파일에 선언된 Intent filter 와 비교하는 방법을 사용하여 해당 구성요소를 요청해 불러오기 때문이다. 호환되는 인텐트가 여러개인 경우 사용자에게 대화상자를 표시하여 선택할 수 있게 하기도 한다. 

 

암시적 인텐트는 세 가지의 하위 요소로 이루어져 있다. 

 

  • <action> : name 특성에서 허용된 인텐트 작업을 선언
  • <data> : 허용된 데이터 유형을 선언
  • <category> : name 특성에서 허용된 인텐트 카테고리 선언 

 

manifest에서 Intent filter 를 사용하는 예시는 다음과 같다.

 

<activity android:name="MainActivity">
    <!-- 어플을 키자마자 보이는 launcher activity 를 설정 -->
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity android:name="ShareActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

 

여기서 주의해야 할 점은, 암시적 인텐트를 수신하려면 CATEGORY_DEFAULT 카테고리를 인텐트 필터에 포함해야 한다. startActivity(), startActivityForResult() 메서드는 CATEGORY_DEFAULT 범주를 선언한 것으로 모든 인텐트를 취급하기 때문에 이 카테고리가 선언되어있지 않으면 activity에서 암시적 인텐트를 확인할 수 없게 된다. 

 


 

지금까지 아무 생각없이 사용하던 Intent 와 Intent filter에 대해서 자세히 공부하고 이해할 수 있어서 뿌듯했다. 안드로이드 공식 문서에 설명이 잘 되어 있으니 예시 코드 등은 공식 문서를 참고 바란다. 

'Android 공부' 카테고리의 다른 글

20. 안드로이드 멀티스레드  (0) 2023.02.02
19. 안드로이드 Manifest  (0) 2023.02.01
17. 안드로이드 Room  (0) 2023.01.30
16. 안드로이드 Retrofit  (0) 2023.01.27
15. REST API 에 대하여  (0) 2023.01.26