어쩌다보니, 액티비티와 뷰, 윈도우, 위젯의 관계에 대해서 생각하고 있습니다.
이거 정말 진짜 완전 굉장히 어려운 주제군요 ^^;

어떻게 딱 잘라서 정의내리기 어려운 내용입니다.

우선 안드로이드의 컨셉에 대한 얘기도 필요할 것이며,
이녀석들이 누구를 상속받았고 어떻게 쓰이기 위해 존재하는 녀석들인지, 또 어떻게 상호작용하는지까지 가려면,
엄청 오래 걸릴듯 합니다.

여기 적혀있는 내용은 정답이 아니라는 얘기를 먼저 드립니다. 완벽하게 틀렸을수도 있고, 얼추 맞을수도 있으며,
대충 얼버무리기도 할 것입니다.


여기에 나오는 내용들은 안드로이드 개발자페이지 레퍼런스들을 참고로 하였습니다.
http://developer.android.com/reference/







 class Window : android.view.Window : 안드로이드 레퍼런스 링크


먼저 Window 클래스를 보면, Overview에 개괄적인 내용들이 나와있습니다.

Window는 top-level 윈도우가 어떻게 보여지는지, 어떻게 동작하는지에 대한 추상 기본 클래스이다.
이 클래스의 인스턴스는 top-level 뷰로 윈도우 매니저(WindowManager)에 추가되서 사용될 것이다.
Windows 클래스는 background, title area, default key processing 같은 표준 UI 정책을 규정한다.
후략..

잠깐 살펴본 내용으로 생각해보면,
윈도우 클래스는 top-level 윈도우가 어떻게 보여지고 동작하는지에 대해서,
배경이나, 타이틀의 영역, 기본적으로 동작하도록 되어있는 키의 처리에 대한 표준 UI정책을 지원하고,
윈도우매니저에 추가되어져서 사용되는 녀석이라는 겁니다.

Window는 화면의 틀을 만드는 것, 기본적인 UI에 대한 것에 관련된 녀석이라는 얘기죠.

그 안에서 무엇을 보여줄것인지는 View에서 이야기 됩니다.







 class Activity : android.app.Activity : 안드로이드 레퍼런스 링크 


Activity는 기본적으로는 Context를 상속받았고, android.app 이라는 패키지 안에 있는 녀석입니다.
그리고 안드로이드 프로젝트에 기본적으로 포함된 android.jar의 Activity.class를 보면, 아래의 녀석들이 확장되어 있다고 나오는군요.

public class android.app.Activity extends android.view.ContextThemeWrapper implements android.view.LayoutInflater$Factory, android.view.Window$Callback, android.view.KeyEvent$Callback, android.view.View$OnCreateContextMenuListener, android.content.ComponentCallbacks 

여기를 보면 Activity는 ContextThemeWrapper를 상속받았고,
여러 클래스들을 구현하고 있습니다. 그 중에 방금 보고 내려온 Window도 보이는군요.

위에서 언급했듯이 Window 클래스는 화면에서 어떻게 보여지고 어떻게 동작할지에 관련된 녀석입니다.
또 WindowManager와 통신할 수 있게 해주는 녀석이죠.

Activity는 Window를 구현함으로써 WindowManager와 소통할 수 있게 된다는 얘기입니다.

Activity는 하나의 애플리케이션 단위로서 화면에 보여지는 녀석이기 때문에,
보여지는 것들, 동작하는 것들에 대한 정의는 매우 중요합니다. 
화면 설정을 Window를 통해서 할 수 있게 되는것이죠.


여기서 잠깐 Activity(액티비티)에 대한 다른 얘기를 하고 넘어가겠습니다.
안드로이드에서 Activity라는 단위는 우리가 보통 생각하는 하나의 애플리케이션 단위입니다.
화면에 보여지는 하나의 액티비티는 하나의 애플리케이션이나 마찬가지라는 얘기죠.

하나의 액티비티가 있을 때,
이 액티비티에 대한 접근은 해당 액티비티 내부가 아닌이상 굉장히 어렵게 되어있습니다.
해당 액티비티안에서는 여러가지를 할 수 있지만,
그 액티비티가 화면에서 벗어나는 순간, 액티비티에 접근하려면, 여러가지 우회적인 방법을 통해서만 가능하게 됩니다.

예를 들어 액티비티와 액티비티간의  데이터교환도 Intent와 onActivityResult()라는 메소드를 통해서 가능하다던가 하는 것들이 그 예입니다.

이건 안드로이드 컨셉에 있어서 매우 중요한 얘기입니다.
내가 만든 애플리케이션내에 있는 하나의 액티비티를 다른 애플리케이션에서 호출 할 수 있습니다.
또 내가 만든 애플리케이션도 다른 애플리케이션들의 액티비티를 호출 할 수 있습니다.
이런것들만 보아도 액티비티는 단독으로도 문제없이 온전한 상태로 실행될 수 있도록 해줘야 하는것입니다.
다른 액티비티와 의존관계를 가지고 있는 액티비티는 안드로이드안에서 확장성을 갖지 못하게 되는거죠.

다른 경우를 예로 들어보면,
[A액티비티 ->  B액티비티 -> C액티비티] 이런 순서로 실행했을 때, C액티비티에서 에러가 발생한다고 해봅시다.
그럼 C액티비티만 종료되고 B액티비티로 이동하는 상황을 보신적이 있으실 겁니다.
서로가 서로에 대한 의존관계가 없기때문에 영향을  미치지 않고 자신(C액티비티)만 종료되고 애플리케이션은 그 상황에서도 종료되지 않을 수 있는것입니다.

1. Activity(액티비티)는 독립성을 갖는다. 혼자서도 존재할 수 있는 애플리케이션이다.
2. Activity(액티비티)와 Activity의 데이터교환은 intent와 구현된 메소드를 통한다. 







 class View : android.view.View : 안드로이드 레퍼런스 링크 


 뷰와 위젯 관련 글 : [Android] 뷰와 위젯, 그리고 앱 위젯 / View, Widget and AppWidget : http://croute.me/391 

위에서 나온 내용들을 다시한번 짚고 View에 대해서 얘기해 보도록 하겠습니다.

짧게 두줄로 줄여보면 아래와 같습니다.
Activity는 화면에 보여지는 하나의 애플리케이션 단위이다. 
Window를 통해서 화면에 대한 설정을 정의할 수 있다.
   

모바일 애플리케이션은 사용자에게 보여지는 부분이 굉장히 중요합니다.
지금까지 보여지는 것의 "틀"에 대한 이야기를 했다면,
이제부터는 무엇을 보여줄지, 어떤 방식으로 보여줄지에 대한, 보여지는 것 자체에 대한 이야기입니다.

View라는 녀석은 사용자에게 직접적으로 노출이 되는 부분입니다.
빌딩이 하나 있다고 생각해 봅시다.
빌딩에는 들어가는 문이 있을 것이고, 건물을 구성하는 벽돌같은 게 있을수도 있습니다. 또 조명같은것들도 있을 수 있고, 창문이 있을수도 있습니다. 건물에 어떤건물인지 보여주는 간판같은게 있을수도 있구요.
이 하나 하나들은 모두 View입니다. 이것들이 모여서 View가 되는거죠.
실제로 밖으로 보여지고 소통하는 부분들은 모두 View라고 볼 수 있습니다.
화면을 구성하는 모든것, 건물을 구성하는 모든 것들은 View입니다.

레퍼런스를 보면 한줄로 간결하게 설명이 되있군요.
This class represents the basic building block for user interface components.
이 클래스는 유저 인터페이스(UI) 컴포넌트를 위한 기본 빌딩 블럭을 대표한다.

어쨋든 기본이 되는 녀석이라는 얘기입니다.

여기서 잠깐 생각하고 갈것은, View와 ViewGroup과 widget입니다.
 1. 뷰 그룹은 자신의 자식(child)으로 뷰를 가질 수 있다.
 2. 뷰 그룹은 뷰이다.
 3. 위젯은 뷰이다. 
 4. 뷰 그룹은 복수의 자식을 가질 수 있다. 

: 뷰는 화면을 직사각형 모양으로 일부분 점유하고 있는 영역입니다. 즉 화면에 보여지는 부분들을 말합니다.

위젯 : (위젯 패키지 내의 클래스들) 뷰를 상속받았습니다.
         이미지를 보여주거나, 텍스트를 보여주거나, 리스트를 보여주거나,
         또는 어떤 이벤트에 대한 처리를 해주는 뷰들입니다.
         화면에 보여지는 것에 대해서 기능을 나누어 두었다고 생각하면 됩니다.

뷰 그룹 : 뷰를 상속받았습니다. 뷰 그룹은 위젯입니다. 
             뷰 그룹은 위젯을 자식으로 가질 수 있습니다. 복수의 자식도 가능합니다.
             뷰 그룹은 화면을 구성하는 것(Layout)에 대해 프로그래머가 컨트롤 할 수 있게 해 줍니다.


이런식으로 생각해 본다면, 뷰는 화면을 구성하는 것들이라고 정의할 수 있습니다.

액티비티에서 실제로 사용할때는 Window를 구현해서 사용할 수 있게된 setContentView()같은 메소드들을 이용합니다.
대표 View를 액티비티에서 구현한 윈도우와 매칭시킨 뒤, 그 대표 View에 여러 뷰(뷰그룹, 위젯들)을 추가(자식)하면서 화면을 구성하는 것이죠.

화면 구성(레이아웃) 관련글 링크
 [Android] 뷰와 위젯, 그리고 위젯 / View, Widget and AppWidget
 [Android] FrameLayout 사용(안드로이드 : 프레임레이아웃의 사용)
 [Android Layout] 0. 레이아웃이란?
 [Android] Layout XML - layout_weight
 [Android Layout] 1. 레이아웃들의 속성 - 레이아웃을 컨트롤하기








 package android.widget : 안드로이드 레퍼런스 링크

이번에는 android.widget 이라는 패키지에 대해서 살펴볼 차례입니다.
이 패키지 안에는 우리가 생각하는 화면 구성 요소들이 거의 모두 들어있습니다.

예를 들어 ListView 라던지, Button, ImageButton, ImageView, TextView,
RatingBar, SeekBar, LinearLayout, RelativeLayout 등이 모두 여기에 있습니다.

아래는 패키지로 분류된 뷰 그룹, 위젯들에 대한 클래스 다이어그램입니다.


이 클래스 다이어그램을 보고 나면, 왜 모두 뷰라고 하는지, 또 왜 위젯이라고 하는지 이해할 수 있습니다.
모두 뷰 또는 뷰 그룹을 상속받았고(뷰 그룹도 뷰를 상속받았다.) 모두 android.widget이라는 패키지에 들어있기때문이죠.

[뷰]라는 단어는 대표적으로 사용되는 단어이고 개별적으로 이야기 할때는 [위젯]이라고 표현할 수 있겠습니다.
또 더 세부적으로 들어가면 해당하는 클래스 이름(TextView나 ImageButton, LinearLayout 같은)을 사용하면 되겠지요.

어떤 위젯들이 존재하는지를 알고, 상황에 따라 적절한 위젯을 화면에 배치해 주는 것이 best입니다.
저는 TabWidget이 있는지 몰랐을 때, 직접 탭이 레이아웃을 구성하고 구현하기도 했었습니다.
또 버튼의 background로 이미지를 사용할 수 있는것을 몰랐을 때는
TextView의 background로 이미지를 쓰고 clickable 속성에 true를 주어 버튼을 만들기도 했었죠.
화면을 원하는데로 구성하고 싶다면 widget 패키지에 어떤 클래스들이 있는지를 보고 사용하면 되는데 그걸 몰랐던 거죠. 

 원문으로 되어있는 레퍼런스들은 매우 많은 도움이 됩니다.
 저도 부족한 영어실력에 땀을 뻘뻘흘려가며 레퍼런스들을 읽으며 많은 것들을 배우고 있죠.
 안드로이드 개발자 페이지의 레퍼런스를 읽지 않고 안드로이드 개발을 잘하고 싶다는 것은,
 자기 자신에 대한 지나친 믿음과 욕심입니다.
 사실 여러 커뮤니티에서 묻고 답하는 내용의 대부분은 레퍼런스를 한번만 더 들여다본다면 찾을 수 있는 것들이죠.





이제 다시한번 정리를 해 보도록 하겠습니다.

Window는 사용자에게 보여질 화면의 틀에 대한 설정, 기본 인터페이스에 대한 설정을 할 수 있는 추상 클래스 입니다.
Activity는 Window를 구현해 WindowManger에 화면을 등록함으로써 자신이 어떻게 보여질지를 정합니다.
View는 모든 위젯들의 대표격으로서 화면에 무엇을 보여줄지, 어떤것을 어떻게 보여줄지를 담고 있는 녀석입니다.
View를 Activity(Window)에 셋(매칭)하고, 해당 View(뷰)에 여러 뷰(위젯, 뷰그룹)을 자식뷰로 추가함으로써 화면을 구성할 수 있습니다.

대충이나마 정리를 하고 보니 서로 엮이고 엮여있는 관계군요.


Posted by croute

댓글을 달아 주세요

  1. 시선 2014.05.30 11:30 신고  댓글주소  수정/삭제  댓글쓰기

    궁금하던 내용인데 정리해주셔서 참고가 되었습니다. ^^