CAFE

15. Activity에 대해서 - Intent 편(1)

작성자슈퍼성근|작성시간11.04.12|조회수8,895 목록 댓글 44

슈퍼드로이드 카페의 안드로이드 강좌가 책으로 나왔습니다.

도서명 : 이것이 안드로이드다.

도서링크 : http://www.yes24.com//24/goods/13950202

================================================================================================


1. Intent 란?

 

Intent를 설명하기 앞서

패키지(application)를 구성하는 4대 요소 Components가 있다고 설명하였다.

현재는 그중 하나인 Activity에 대해서 설명하고 있다.

 

각 Component(Activity,...)는 어떻게 활성화 될까?

다시 말해 어떻게 실행이 될까?

 

Component는 ActivityManager Service에 의해서 실행된다.

물론 ActivityManager Service에게 특정 Component를 활성해 달라고

요청하는 것은 Component이다.

즉 Component에서 특정 Component를 실행해 달라고

ActivityManager Service에게 요청하고

요청이 수락되면 Activity Service는 해당 Component를 활성화(실행) 시켜 준다.

 

아래를 잠시 보자.

위와 같이 Component를 활성화 하는 것은 ActivityManager이다.

그런데 PackageManager는 무엇일까?

 

각종 Application이 설치가 되면

설치된 정보를 어딘가 저장할 것이다.

즉 각종 설치된 Application의 정보를 가지고 있는 것이 PackageManager 이다.

 

왜 어렵게 이 두가지를 설명할까 라고 생각하는 분들이 많을 것이다.

하지만 이 두가지 서비스의 역할을 모르면

안드로이드 자체를 이해하기가 어렵다. ^^

 

이 두가지 서비스는 긴밀한 사이이다.

ActivityManager가 특정 패키지의 Activity(Component)를 활성화 하고

관리할때, PackageManager에 해당 패키지 정보를 참조하기 때문이다.

PackageManager가 없다면  ActivityManager는 바보가 되는 것이다.

 

다시 정리해 보자.

Component에서 특정 Component를 실행해 달라고

ActivityManager Service에게 요청하고

요청이 수락되면 Activity Service는

해당 Component가 유효한지 PackageManager에게

Component 정보를 요청한다.

ActivityManager는 PackageManager에게 받은 정보를

확인하고 해당 Component를 활성화(실행) 시켜 준다.

 

자 이때 하나가 빠진 것이 있다.

Component에서 ActivityManager에게 특정 Component를

실행해 달라고 요청하는 과정에서

ActivityManager에 의해 실행될 Component의 정보 이다.

 

그 것이 바로 Intent이다.

Intent는 활성화 될 Component의 정보 그 자체이다.

 

아래에서 Intent Class를 보자

이전 강죄에서 배운 Parcelable 객체를 상속 받았다.

그것은 바로 이 Class가 IPC 통신을 위한 직렬화 객체라는 것이다.

즉 이 객체는 다른 Process로 전달하기위한 데이터 그 자체라는 의미이다.

 

많은 사람들이 Intent 자체에 많을 의미를 부여하고,

Component를 활성화하는 대상이라고 착각하는 경우가 있다.

하지만 Intent 객체의 목적은 안드로이드 상에서 Component들을

활성화하고 제어하기 위한 규격화 된 정보 그 자체일 뿐이다.

 

앞으로 Intent에

각 Component가 어떤 정보를 실어 보내고,

그 정보를 받은 ActivityManager가 어떤 처리를 해서,

Component가 활성화 되는지 알아 볼 것이다.

(사실 이 것들이 Intent에 대한 설명의 대부분이 될 것이다.)

 

아래 그림을 보고 하나하나 정리해 보자.

 

패키지 A에 Component Acitivty에서

패키지 B의 Component들을 호출한다.

이때 Intent가 활성화 될 Component 정보를 담고 있다.

A 패키지의 Activity에서 Intent 정보를 어떻게 담는냐에 따라

B 패키지의 Components 중 Activity 혹은 Service, Broadcast Receiver가 호출되는 것이다.

 

 

이렇게 Intent 정보를 이용하여

Component를 활성화 하는 것은

위와 같이 Activity, Service, Broadcast Receiver 3가지 이다.

(Content Provider는 Intent를 이용하지 않는다.

 Content Provider에 대해서는 다음에 강좌로 진행될 것이다.)

 

아래는 Intent에 담을 정보에 대해서 설명하였다.

그림과 같이

활성화 될 Component 정보(이름)와

활성화 될 Component에 전달될 데이터 이다.

 

아래는 Component가 ActivityManager에게 특정 Component 활성화를 요청할때의

활성화 될 Component 종류에 따라 호출할 함수들을 나열하였다.

즉 Activity를 활성화 할때는 startActivity()란 함수를 사용하고

    Service를 활성화 할때는 startService(),

    Broadcast Receiver를 활성화 할때는 sendBroadcast() 함수를 사용하는 것이다.

 

혹시 오해가 생길까봐 아래의 설명을 덧 붙인다.

Component 활성화는 내부 Component에서 내부 Component를 호출할 수도 있고

내부 Component에서 외부 Component도 호출할 수도 있다.^^

 

아래는 위에서 설명한 ActivityManager와 PackageManager를 포함한

Component 활성화 과정이다.

1번에서 활성화할 Component의 정보 즉 Intent를 작성하고

2번에서 startActivity()등의 함수로 ActivityManager에게 활성화를 요청한다.

3번과 4번에서 활성화 될 Component 정보가 유효한지 그리고 활성화 하기 위한

                    Component의 패키지 정보를 PackageManager에 요청한다.

5번과 같이 PackageManager는 해당 Component 정보를 탐색하고

                탐색된 Component 정보를 다시 ActivtyManager에게 전달한다.

6번에서 ActivityManager는 전달받은 Component 정보를 기반으로

           해당 Component를 활성화 시킨다.

7번과 8번에서 해당 활성화 될 Component는 Intent정보를 넘겨 받고 드디어 활성화 된다.

 

이후 활성화 된 Component는 ActivityManager에 의해 계속 관리된다.

 

 

다시 아래와 같이 가 역할에 대해 확인하자.

 

 

PackageManager는 설치된 모든 패키지에 대한 정보를 가지고 있다 하였다.

이 정보는 ADB를 통해 보는 방법이 있다.

아래와 같이 입력해 보자.

(물론 Android 애뮬을 구성한 다음 실행하여야 한다.)

 

 

아래와 같이 설치된 모든 패키지의 정보나 출력될 것이다.

너무 길어서 보기가 힘들 것이다.

아래와 같은 방법으로 해당 내용을 파일로 저장하여 확인하는 것이 편하다.

 

>> adb shell dumpsys package > 파일명

 

 

PackageManager에 저장되는 패키지 정보는

패키지의 어떤 데이터를 참조하여 구성되는 것일까?

바로 패키지 마다 하나씩 무조건 존재하는 AndroidManifest.xml 이다.

AndroidManifest.xml은 패키지 내에 포함된 모든 Components에 대한 상세 정보를 포함할 뿐만아니라,

패키지에 대한 다양한 정보를 모두 담고 있다.

AndroidManifest.xml에 대해서는 별도의 강좌를 진행 중이다.

본 강좌를 진행하면서 AndroidManifest.xml의 내용에 대해 다루도록 하겠다.

 

이해를 돕기 위해

sample application을 하나 작성하자.

나 같은 경우는 HelloAndroid를 아래와 같이 하나 작성하였다.

위와 같이 작성한 Application을 설치해 보자.

 

설치한뒤 아래와 같이 ADB 명령어를 실행해 보자.

특정 패키지 정보만 보기 위해서는 아래의 명령어로 가능하다.

 

>> adb shell dumpsys package 패키지명

아래는 결과 화면이다.

 

패키지 정보내에 AndroidManifest.xml의 내용이 포함된 것을 알 수 있다.

 

차후 설치된 Package에 대한 정보를 알고자 할때 아주 유용한 것이다.

이것 말고도 "pm" 명령어를 통해 좀더 상세한 정보를 얻을 수도 있다.

이것은 PackageManager에 대한 강좌를 별도로 진행시에 언급하도록 하겠다.

 

 

2. Activity Component에서 Intent 활용 

 

안드로이드에서는 Intent를 작성하고

ActivityManager를 통해 Comonent를 활성화 하는 방식이 두가지가 존재한다.

 

아래의 그림을 보자.

 

활성화할 패키지명과 Component명을 정확히 지칭하여

Component를 활성화하는 방법이다.

이를 Explicit(명시적) Intent라고 한다.

 

아래의 그림을 보자.

 

이번에는 활성화 할 Component의 정보를 알지 못하는 경우이다.

순수하게 활성화 할 Component의 동작 만으로

원하는 Component 활성화를 요청하는 경우이다.

ActivityManager는 이 경우 해당 동작에 해당하는

Component를 찾아서 활성화 시켜준다.

위와 같이 하나 이상 같은 동작을 가진 Component가 존재한다면

ActivityManager는 선택할 수 있는 기회를 주고

사용자로 의해 선택된 Component를 활성화 시켜 준다.

이런 방식을 Implicit(암시적) Intent라고 한다.

 

여기서 잠시 생각해 보자.

Google에서 Intent를 왜 Intent라고 지었을까?

Intent의 뜻은 의도, 목적 등의 뜻을 가진다.

필자는 암시적 Intent에서 그 이유를 이해하려고 하였다.

암시적 Intent의 경우 Component를 활성화 할때,

순수하게 자신의 의도만 전달하였다.

그러므로 Intent라는 단어를 사용한 것이라 유추한다. (^^;)

 

 

2.1 Activity Component 활성화 (명시적 Intent 이용)

일단 간단한 Sample 코드를 살펴보자.

 

한 패키지에서 다른 패키지에 있는 Component를 활성화하는 코드를 작성해 보겠다.

 

아래는 일단 활성화 될 패키지이다.

Component 종류는 Activity이다.

해당 Component의 패키지 명은 "com.test.ActivityCallee" 이다.

그리고 Component 명은 "com.test.ActivityCallee.ActivityCallee" 이다.

이 정보를 이용해서 해당 Component가 활성화 되므로 기억하자.

 

실행하면 아래와 같은 Activity가 실행될 것이다.

 

자 아래는 활성화를 시도할 패키지이다.

1번과 같이 버튼을 하나 생성한고

2번에서 Intent 정보를 하나 생성한다.

Intent 정보에는 활성화 할 Component 정보를 넣는다.

(위에서 기억하라고 했던 Component 정보를 입력해 주면 된다.)

ComponentName 이라는 객체는 Component의 기본 정보를 가진다.

 

3번에서 startActivity()라는 함수를 통해

ActivityManagerService를 통해 Component를 활성화 하도록 유도한다.

 

자 실행보면

아래와 같이 버튼을 눌렀을때 해당 Component가 활성화 되는 것을 볼 수 있다.

 

위와 같이 특정 Component를 활성화하는 방법을 살펴 보았다.

그리고 지금까지 Component를 활성화 하는 것은 무엇이라고 하였는가?

바로 ActivityManagerService라고 했었다.

ADB Shell에서 ActivityManagerService를 이용할 수 있는 명령어가 있다.

아래를 보자.

 

AM start -n 패키지명/component명

위와 같은 명령어로 어떤 Activity Component도 활성화 할 수 있다.

이런 편리한 명령어는 무조건 기억하라.

차후 다양한 Test를 위해 많이 사용된다.

이 명령어를 모르면 특정 Componet를 활성화 하기 위해

늘 활성화하는 패키지를 만들어 주어야 한다.

 

아래는 본 Sample 소스 코드이다. 참조하자. 

 

첨부파일 ActivityCallee.zip

첨부파일 ActivityCaller.zip

 

위에서 ComponentName 객체를 통해 활성화 될 Component를

명시적으로 적어 주었다.

명시적으로 Component 명을 확실히 적어 주었으므로

활성화 될 Component는 명확해 진다.

 

이것을 Explicit(명시적) Intent 라고 한다.

 

 

2.2 Activity Component 활성화 (암시적 Intent 이용)

 

이전에 배운 방식과 전혀 다른 방식으로 Component를 활성해 보겠다.

 

일단 간단한 Sample 코드를 살펴보자.

활성화 될 패키지를 아래와 같이 생성하자.

이전과는 좀 다르게

위에서 <intent-filter> 부분을 변경하였다.

이 중 <action android:name="android.intent.action.TEST1"> 부분을 기억하자.

이 패키지를 실행해도 실행되지 않을 것이다.

일단 반응이 없어도 다음으로 넘어가자.

(반응은 없지만 설치는 되어 있을 것이다.)

 

이제 component를 활성화 할 패키지를 만들어 보자.

1번에서 버튼을 하나 생성한다.

2번에서 Intent에 Action을 하나 추가하였다.

자세히 보면 이전에 기억하라는 부분과 동일한 값일 것이다.

 

자 이제 실행해 보자.

이전과 동리한 실행 결과를 볼 수 있다.

 

활성화 될 패키지 정보를 전혀 주지 않았는데 동일한 결과가 나왔다.

무엇인가 느껴지는가?

 

이해를 위해 아래에서 활성화 될 패키지의 소스를 조금 수정해 보겠다.

동일한 패키지에서 Activity Component를 하나더 추가하였다.

3번에서 AndroidManifest.xml에서도 추가된 Activity 정보를

추가해 주어야 한다.

 

아래와 같이 추가하였다.

여기서 주목할 점은

두가지 Activity 모두 <action android:name="android.intent.action.TEST1"> 라고 설정하였다.

일단 설치를 해 보자.

 

자 이제 Component를 활성화하는 이전 패키지를 잠시 보자.

패키지를 활성화 하는 부분은

오로지 "android.intent.action.TEST1" 밖에 없다.

하지만 위에서 활성화 될 패키지의 Component에서

두 Activity 모두 위의 이름으로 설정하였다.

 

그렇다면 이 componet를 활성화하는 패키지를 실행해서

Activity를 활성화를 시도하면 어떤 Component가 실행이 될까?

 

아래는 실행 결과 이다.

재미있지 않은가?

 

2번 을 보면 Action의 이름이 같으므로

어떤 Activity Component를 활성화할지 결정하는 창이 뜨는 걸 볼 수 있다.

 

개인적으로 Android를 처음 접할때 이점을 보고 참 놀랬다.

멋찌지 않는가?

 

일단 위의 sample 소스는 아래를 참조하자.

 

첨부파일 ActivityCalleeImplicit.zip

첨부파일 ActivityCallerImplicit.zip

 

위에서 Component를 활성화 할때 전혀

패키지 명과, Component명을 적어 주지 않았다.

즉 명시적인 Intent가 아니었다.

 

단지 Action이라는 부분을 추가해 주었을 뿐이다.

이 것을 암시적 Intent라고 부른다.

 

암시적 Intent 또한 ADB Shell에서 ActivityManagerService를 이용할 수 있는 명령어가 있다.

아래를 보자.

 

AM start -a "Action명"

 

 

[Tip]

Tip이라고 하여도 꼭 이해하면 좋은 부분이므로 살펴보자.

 

기존 Activity를 호출하는 소스에

아래의 부분을 추가해 보자.

 

아래는 위의 추가된 코드를 통해 출력된 로그이다.

 

PackageManager는 queryIntentActivities() 함수를 통해

암시적인 Intent의 정보 (위에서 Action과 같은)에 해당하는 모든

Component 정보를 ActivityManager에게 전달해 준다.

 

물론 queryIntentActivities()는 ActivityManager에서 뿐만 아니라,

일반 사용자도 사용할 수 있는 함수 이다.

(앞으로 많은 곳에서 활용할 수 있을 것이다.)

위에서 queryIntentActivities()의 결과 로그를 보라.

 

 

 

 !!! 위의 주제에 해당하는 적당한 예를 댓글로 남겨 주세요. ^^

    활용 방안의 예는 다른 개발자들에게 많은 도움이 됩니다. 


!!! 카페의 활성화를 위해 추천 버튼을 눌러 주세요. 



다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
  • 답댓글 작성자슈퍼성근 작성자 본인 여부 작성자 | 작성시간 14.09.24 많은 도움 되셨으면 좋겠네요. 감사합니다.
  • 작성자droy | 작성시간 15.05.19 감사합니다
  • 작성자quki | 작성시간 15.07.14 감사합니당^^
  • 작성자컴공도리 | 작성시간 15.07.15 강의 흐름이 너무 좋습니다. 이해가 잘 되네요. 꼭 책 사서 봐야겠네요^^ 감사합니다.
  • 작성자dlrlwk | 작성시간 16.03.09 내용흐름이 너무 잘 정리 되어있고 자세히 설명되어 있어서 여태 본 자료중 가장 좋은것 같습니다. 감사합니다.
댓글 전체보기
맨위로

카페 검색

카페 검색어 입력폼