2010년 7월 29일 목요일

Using Eclipse(이클립스 사용하기)

이클립스 사용하기

이 문서에서는 Android 플랫폼 개발을 하기 위해 Eclipse IDE 를 설정하는 것을 도와줄 것이다.

주의 : 만약 이클립스로 안드로이드에서 돌아가는 어플리케이션 개발하는 방법에 대한 정보를 찾고 있다면, 이 페이지는 당신에게 적합하지 않다. the Eclipse page on developer.android.com 에서 정보를 찾는 것이 더 유용할 것이다.

이클립스에 들어가기
기본 설정
첫째로, 정규 Android 개발 시스템 설정을 확실히 해 두는 것이 중요하다.
cd /path/to/android/root
make      # 아직 실행하지 않았다면 좀 기다려라.
중요 : 당신은 여전히 에뮬레이터나 디바이스에서 실제 실행될 파일을 빌드하기 위해서 "make"를 사용할 것이다.
Eclipse는 파일 수정과 컴파일을 확인하는데 사용할 것이나, 어떤 make 해야 하는 파일을 수행할 때는 이클립스에서 저장하고, shell에서 "make"한다. 이클립스 빌드는 단지 에러 체크만 할 뿐이다.

Eclipse는 Java 파일들을 검색할 디렉토리 목록을 필요로 한다.
이것은 "Java Build Path"라 불리며 .classpath 파일에서 설정될 수 있다.  
아래에 예가 나와 있다.
cd /path/to/android/root
cp development/ide/eclipse/.classpath .
chmod u+w .classpath #make the copy writable
이제 필요하다면 .classpath의 복사본을 수정한다.

증가하는 Eclipse의 메모리 설정
Android 프로젝트는 Eclipse의 자바 VM이 컴파일 중에 종종 메모리가 부족할 정도로 크다.
이런 문제를 피하려면 eclipse.ini 파일을 수정하면 된다.
Apple OSX 에서 eclipse.ini 파일은 /Applications/eclipse/Eclipse.app/Contents/MacOS/eclipse.ini 에 위치하고 있다.

메모리 관련 기본값(Eclipse 3.4 기준)
-Xms40m
-Xms256m
-XX:MaxPermSize=256m

Android 개발에 권장되는 설정값
-Xms128m
-Xmx512m
-XX:MaxPermSize=256m

이 설정값들은 Eclipse의 최소 Java heap 사이즈를 128MB, 최대 Java heap 사이즈를 512MB, 그리고 최대 지속 생성 사이즈를 기본 256MB로 유지하도록 설정한다.

이제 이클립스를 시작한다:
eclipse    # 원한다면 아이콘을 클릭하여 실행해도 상관없다.

다음은 Android 개발을 위한 프로젝트를 생성한다:
1. Eclipse가 workspace location을 묻는다면, 디폴트로 선택한다.
2. "Welcome"스크린이 뜨면 닫는다. 그럼 Java perspective가 보일 것이다.
3. File > New > Android Project
4. Project name 란에는 "android"나 원하는 이름을 넣는다.
5. "Create project from existing source" 를 선택하고, 당신의 Android 루트 디렉토리의 경로를 입력한 후 Finish를 클릭한다.
6. 프로젝트를 세팅하는 동안 기다린다.(우측 하단 모서리에서 자세한 진행 바를 볼 수 있다)

프로젝트 워크스페이스가 생성되면, Eclipse는 빌딩을 시작한다. 이론상으로는, 에러없이 빌드 되어야 하며, 당신이 설정을 해야 한다. 필요하다면, 강제 리빌드를 위해서 Project Build Automaticallry 를 체크 해제하거나 다시 체크 한다.

주의: Eclipse 는 종종  당신의 파일들의 상단에 리소스들을 사용하는 "import android.R" 문장을 추가하기도 하는데, 특히 당신이 eclipse에 import들을 정렬(sort)이나 그 밖에 방법으로 관리하는것을 요청했을때 발생할 가능성이 높다.
이것은 당신의 make가 실패 하게 되는 원인이 될 것이므로 이런 잘못된 import문들을 찾아서 제거해야 한다.

동기화 할 때
당신이 repo sync 를 할 때마다, 또는 그 밖의 방법으로 Eclipse 밖에서 파일들을 변경할 때마다(특히 .classpath), 다음의 방법으로 Eclipse 뷰들을 새로고침 해야 한다:
1. Window > Show View > Navigator
2. "Navigator"의 프로젝트에서 마우스 오른쪽 버튼 클릭.
3. 콘텍스트 메뉴(마우스 오른쪽 버튼 클릭하면 뜨는 메뉴)에서 Refresh 클릭

빌드 패스에 앱 추가하기
기본 .classpath 는 core system과 앱들의 샘플 모음 소스들을 포함하고 있지만, 당신이 작업할 특정 앱에는 그렇지 않을 것이다.
앱을 추가 하려면, 앱의 소스 디렉토리를 추가해야 한다.
Eclipse에서는 다음과 같이 한다:
1. Project > Properties
2. "Java Build Path" 를 좌측의 메뉴에서 선택한다.
3. "Source" 탭을 고른다.
4. "Add Folder..." 를 클릭한다.
5. 당신의 앱을 "src" 디렉토리에 추가한다.
6. OK를 클릭한다.

위의 과정을 마치면, 리스트의 "source folder"에 android/packages/apps/YourAppName/src 와 같이 보여야 한다. 당신이 어떤 앱(들)을 포함시켰냐에 따라, othersrc/main/java 디렉토리들을 android/dalvik/libcore 아래에 포함시킬 필요가 있다.

.....번역중..

"Eclipse가 제대로 동작하지 않아요, 어떻게 하죠?"
다음을 확인해 보자:
    - 당신이 이 페이지의 과정을 정확히 따라한것인지
    - 당신의 문제들이 어떤 에러들을 보여주지는 않는지
    - 당신의 어플리케이션이 package/directory 구조를 지키고 있는지

그래도 문제가 있다면, 안드로이드 메일링 리스트나 IRC 채널중 한곳에 문의하도록 해보자.


원문 : http://source.android.com/source/using-eclipse.html 

2010년 7월 25일 일요일

안드로이드란?

안드로이드가 뭔지 공식 사이트를 보면 다음과 같다. 지금껏 3년간 C/C++로 개발을 했지만, 이 자바를 이용한다는 것... 자바를 무려 10년(헉 벌써 10년이 됐네..-.-)이나 건드려온 나에게는 정말 희소식이 아닐 수 없다.

안드로이드란?
안드로이드는 OS, Middleware, Key Application을 포함하는 모바일기기의 S/W 집합체이다. 그리고 안드로이드 SDK는 안드로이드 플랫폼상에서 자바 프로그래밍 언어를 이용하여 개발을 시작할 수 있도록 툴과 API를 제공하고 있다.


특징
- Application Framework : 재사용 가능. 컴포넌트를 교체 가능.
- Dalvik virtual machine : 모바일 기기에 최적화.
- Integrated browser : Open Source WebKit 엔진 기반.
- Optimized graphics : custorm 2D graphics 라이브러리로 개발. OpenGL ES 1.0 스펙을 기반으로 하는 3D graphics (하드웨어 가속은 optional)
- SQLite : 구조화된 데이타 저장
- 미디어 지원 : 오디오, 비디오, 이미지 포맷(MPEG4, H.264, MP3, AAC, AMR, JPG, PNG, GIF)
- GSM 지원 : 하드웨어 의존적
- Bluetooth, EDGE, 3G, and WiFi 지원 : 하드웨어 의존적
- 카메라, GPS, Compass(나침반), Accelerometer(가속도계) 지원 : 하드웨어 의존적
- Rich 개발 환경 : 디버깅, 메모리, 성능 프로파일링, Eclipse IDE plugin을 위한 에뮬레이터, 툴 제공

안드로이드 아키텍처
 
위 그림에서 볼 수 있는것과 같이 Application, Application Framework, Libraries, Android Runtime, Linux Kernel로 나누어져 있다.

Applications :
안드로이드는 Email Client, SMS Program, Calendar, Maps, Browser, Contacts등의 핵심 응용프로그램을 탑재할 것이다. 모든 프로그램은 자바로 개발된다.

Application Framework : 개발자는 핵심 응용프로그램에서 사용된 것과 같은 프레임워크 API에 모두 접근 가능하다. 응용프로그램 아키텍쳐는 컴포넌트 재사용을 손쉽게 할 수 있도록 되자인 되었으며, 어떤 응용프로그램의 기능으로 제작하거나 제작하는데 사용된다.(단, 프레임워크의 보안 제약을 따라야 한다.) 이같은 메카니즘은 컴포넌트를 사용자에 의해 교체할 수 있도록 한다.

Libraries : 안드로이드는 안드로이드 시스템에서 다양하게 사용되는 C/C++ 라이브러리들을 포함하며, 안드로이드 Application Framework를 통해 개발자들은 이런 사항을 알 수 있다.


  • System C library  :  임베디드 리눅스 기반 기기를 위한, 표준 C 시스템 라이브러리(libc)의 BSD 상속 구현체
  • Media Libraries : PacketVideo의 OpenCORE 기반이며, 인기있는 오디오 및 비디오 포맷, MPEC4 / H.264 / MP3 / AAC / AMR / JPG / PNG를 포함하는 정적 이미지 파일의 재생 및 녹음(녹화)
  • Surface Manager : 디스플레이 서브시스템 및 다수의 응용프로그램의 2D, 3D 그래픽 레이어
  • LibWebCore : 안드로이드 브라우저 및 Embeddable 웹 뷰와 같은 최신의 웹 브라우저 엔진
  • SGL : 2D graphics 지원
  • 3D libraries : OpenGL ES 1.0 API 기반를 기반으로 하며, 하드웨어 3D 가속 또는 최적화된 3D S/W rasterized
  • FreeType : 비트맵과 벡토 폰트 렌더링
  • SQLite : 모든 응용프로그램에서 사용 가능한 강력하고 경량인 관계형 데이터베이스 엔진

Android Runtime
안드로이드는 자바 프로그래밍 언어의 핵심 라이브러리 기능 대부분을 제공하도록 핵심 라이브러를 제공한다.
모든 안드로이드 응용프로그램은 각자의 프로세스상에서 실행되며, 고유의 Dalvik 버추얼 머신의 인스턴스를 가지고 있다. Dalvik은 기기가 다수의 버추얼 머신에서 효율적으로 실행될 수 있도록 제작되었으며, 최소의 메모리 영역에 최적화된 Dalvik Executable(.dex) 포맷 파일을 실행시킨다. 버추얼 머신은 레지스터 기반이며, 자바 컴파일러로 컴파일된 클래스들을 "dk"툴을 이용하여 .dex 포맷으로 변경한 클래스들을 실행한다.
Dalvik 버추얼 머신은 스레딩과 저수준 메모리 관리와 같은 리눅스 커널 기능을 사용한다.

Linux Kernel
안드로이드는 보안, 메모리 관리, 프로세스 관리, 네트워크 스택, 드라이버 모델과 같은 리눅스 버전 2.6의 핵심 시스템 서비스를 이용하며, 커널은 하드웨어와 소프트웨어간 추상계층으로 동작한다.

 

 

 

 

 

[출처] http://www.kandroid.org/

 

안드로이드 애플리케이션 구조

안드로이드 애플리케이션 구조


◆ 안드로이드 애플리케이션 구조
안드로이드 애플리케이션은 Activity, Intend Receiver, Service, Content Provider 이 4가지로 구성되어 있다. 모든 애플리케이션이 이 4가지를 다 필요로 하지 않으며, 이들의 조합으로 이루어진다.
애플리케이션에서 어떤 컴포넌트들을 사용할지 결정하였다면 이 컴포넌트들의 목록을 AndroidManifest.xml 파일에 기록해야 한다. 이 xml 파일은 어느 애플리케이션에서 이 컴포넌트들을 선언했는지, 그들의 기능과 요구사항은 무엇인지를 기록하는 파일이다. 추후에 이 파일에 대해 자세하게 설명하도록 하겠다.
 
◆  Activity
Activity는 애플리케이션에서 하나의 화면을 지칭한다. 각 Activity는 Activity base class를 상속하여 구현한 하나의 클래스이며, 사용자에게 View와 event 응답으로 이루어진 인터페이스를 화면상에 보여줄 것이다. 예를들어 텍스트 메시징 애플리케이션은 첫 화면에서 contact의 목록을 보여줄 것이고, 두번째 화면에서는 선택한 contact에게 메시지를 쓸 수 있도록 하고, 나머지 화면에서는 보낸 메시지를 확인하거나 환경설정을 바꾸는 화면이 될 것이다. 이러한 화면이 Activity가 되며, 다른 화면으로의 이동은 새로운 Activity를 시작하는 것과 같다. 어떤 상황에서는 Activity가 이전의 Activity로 값을 보내줄 수도 있다. 예를 들면 사용자가 사진을 선택했을 경우를 이전의 Activity에 선택한 사진을 보내주는 것과 같은 것이다.
화면이 오픈되면, 이전 화면은 멈추게 되며, history stack에 저장된다. 사용자는 history내에 있는 이전 화면으로 돌아갈 수 있다. 화면들은 history stack내에 저장될 필요가 없는 경우 삭제될 수 있으며, 안드로이드는 이 history stack을 home screen으로부터 실행시킨 각 애플리케이션마다 유지하게 된다.
 
* Intent와 Intent Filter
안드로이드는 화면과 화면 사이를 이동할 때, Intent라는 특별한 클래스를 사용한다. Intent는 애플리케이션이 무엇을 하기를 원하는지에 대한 정보를 담고 있다. Intent의 가장 중요한 부분은 action과 data가 어떤 동작을 할 것인지에 대한 자료구조이다. action의 일반적인 값은 MAIN(activity의 시작점), VIEW, PICK, EDIT 등등이며, 데이터는 URI로 표현된다. 예를들어, 어떤 사람의 연락처를 보려고 할 때 VIEW action에 대한 intent를 생성하고 그 사람을 표현하는 URI data를 만들어 VIEW action 데이터로 지정해주면 된다.
이와 관련한 클래스로는 IntentFilter가 있다. Intent가 어떤 작업에 대한 요청이라면 IntentFilter는 Activity(또는 아래에 설명될 Intent Receiver)상의 Intent를 핸들링 할 수 있는지를 표현하는 것이다. 예를 들어, 어떤 사람에 대한 연락처를 보여줄 수 있는 Activity가 사람에 대한 정보를 표현하는 데이터에 적용될 때 VIEW 액션을 핸들링 할 수 있는 IntentFilter를 생성한다. 또한 Activity는 AndroidManifest.xml 파일에 기록된 IntentFilter를 생성한다.
화면과 화면 사이를 네비게이션 하는 것은 Intent를 해석하는 것으로 동작된다. 앞으로(forward) 네비게이션 하려면 Activity는 startActivity(myIntent)를 호출하고, 그 다음에 시스템은 애플리케이션에 설정된 모든 IntentFilter를 검사하고, myIntent와 가장 일치하는 IntentFilter를 가진 Activity를 가져오며, 이  Activity의 시작을 Intent로부터 통보받는다. Intent 해석 과정은 startActivity가 호출될 때 런타임으로 일어난다. 이러한 과정은 아래의 두 가지 장점을 지닌다.
(1) Activity는 다른 컴포넌트들이 간단하게 Intent를 요청하는 것만으로 간단하게 재사용 가능.
(2) 동일한 IntentFilter를 가진 새로운 Activity로 Acitivity는 언제든지 교체 가능..
 
◆ Intent Receiver
IntentReceiver는 작성한 애플리케이션 코드내에서 핸드폰에 통화가 걸려오거나, 데이터 네트워크 접속이 활성화되는 것과 같은 외부 이벤트를 처리하는데 사용된다. IntentReceiver는 UI를 그려주는 것은 아니고, NotificationManager를 이용하여 사용자에게 어떤 일이 발생했다는 것을 알려준다. IntentReceiver도 AndroidManifest.xml 파일에 등록되지만, Context.registerReceiver()를 이용하여 코드상에서 등록해줄 수도 있다. 애플리케이션이 호출되어야 하는 자신의 IntentReceiver에 의해 실행할 수 없을 때는 IntentReceiver가 트리거 되면 필요에 따라 시스템이 애플리케이션을 실행한다. 또한 애플리케이션은 Context.bradcastIntent()를 호출하여 자신의 Intent를 다른 애플리케이션에 broadcast할 수 있다.
 
◆  Service
Service는 UI와 상관없이 아주 오랫동안 존재하며 실행되는 코드이다. 예를 들면 재생목록에서 노래를 재생하는 미디어 플레이어 같은 것이다. 미디어 플레이어 애플리케이션은 사용자가 곡을 선택하고 재생을 시작하게 하는 하나 이상의 Activity를 가지고 있지만, 스스로 음악 재생을 하는 것은 Activity에 의해 실행되는 것은 아니다. 사용자는 새로운 화면으로 이동하고 나서도 음악을 계속 재생하기를 기대하기 때문이다. 이런 상황에서 미디어 플레이어의 Activity는 Context.startService()를 이용하면 Service로 실행된다. 시스템은 음악 재생 서비스를 멈출때까지 계속 재생할 것이다. Context.bindService() 메소드는 서비스에 연결하거나 아직 시작하지 않은 Service를 시작한다. Service에 연결이 되면 Service에 접근가능한 인터페이스를 통해 멈춤, 다시 재생등을 할 수 있도록 접근이 가능하다.
 
◆  Content Provider
애플리케이션은 자신의,데이터를 SQLite 데이터베이스 또는 다른 방법으로 파일에 저장할 수 있다. ContentProvider는 애플리케이션 데이터가 다른 애플리케이션과 공유할 필요가 있을 때 아주 유용하다. 이 클래스는 다른 애플리케이션이 데이터를 저장하거나, 가져오는 것과 같은 작업을 할 수 있도록 해준다.
위의 구조와 관련한 것은 다음에 더 자세히 다루고, 실제로 모든 과정을 거치는 코드를 작성해보도록 하자. 아래의 샘플 코드를 1~3을 따라해보면 위에서 언급한 안드로이드 구조를 이해할 수 있다.

 

 

 

 

[출처] http://www.kandroid.org/

 

 

안드로이드 UI 관련 요소 및 컨셉 용어 정리

안드로이드 UI 관련 요소 및 컨셉 용어 정리


아래는 SDK나 여러가지 메뉴얼에 나와있는 공통 UI 요소와 컨셉에 관한 설명이다.
 
Activity
안드로이드 애플리케이션의 표준 화면을 의미한다. Activity는 현재 동작중인 애플리케이션 또는 다른 애플리케이션으로부터 발생한 Intent와 매칭될 때 안드로이드가 실행할 수 있는 클래스라 할 수 있다. 대부분의 경우 UI 이벤트나 복잡한 작업들을 처리하는 전체 화면창으로 보여지지만, 투명 또는 화면상에 떠있는 개체로 표현되기도 한다.
 
View
그리기, 클릭 처리, 키스트로크외 다른 상호작용 이벤트를 처리할 수 있는 사각의 영역이다. View는 대부분의 Activity 또는 Dialong 화면(Text box, window 등)의 base 클래스다. 그리기슬 수행하라는 호출을 해당 객체의 컨테이너로부터 수신하고, 부모 객체에 어느만큼의 영역에 그릴 것인지 통보한다.
 
View Group
다수의 자식 View 객체를 담고 있는 컨테이너이다. 자식 객체들이 어디에 어느만큼의 크기로 배치되는지 결정하고 적절한 시점에 화면상에 그리도록 호출한다. 어떤 것들은 보이지 않고 레이아웃만 나타낼 수도 있고, 다른 것들은 자체적인 UI를 가지고 있을 수 있다. View Group은 모두 widget 패키지에 속해있다.
 
Widget
텍스트 박스와 팝업 메뉴와 같은 폼 엘리먼트를 말한다. 이것들은 자기 자신을 그리고 화면상에 UI 이벤트를 다룬다. Widget은 widget 패키지내에 속한다.
 
Drawable
백그라운드 이미지와 같이 다른 UI 엘리먼트안에 있는 비주얼 엘리먼트를 말한다. 이것은 이벤트를 받지 않으며 "state"와 애니메이션 객체, 이미지 라이브러리와 같은 서브클래스가 동작하도록 해주는 스케쥴링과 같은 다양한 속성을 할당할 수 있다. 많은 drawable 객체들은 이미지 정보를 담고 있는 xml 파일 또는 비트맵 파일 같은 리소스 파일로부터 로드된다.
 
Panel
Panel은 부모 창에서 서로 모여있는 정렬된 View이며, 클릭과 부모와 관련된 간단한 함수 수행을 통해 제어가 가능하다. Panel은 부모의 앞에 떠있는 개체이며, 상대적인 위치를 가지고 있다. 안드로이드에서 구현된 Panel의 전형적인 예로는 모든 스크린에서 사용되는 옵션 메뉴 같은 것이다. 현재는 Panel을 생성하기 위한 특정한 클래스나 메소드는 없다.
 
Dialog
Dialong는 버튼과 간단한 폼으로 동작하면서 이벤트에 반응하고 값을 리턴할 수 있는 떠 있는 윈도우다. 이것은 history stack에서 영속성을 관리하는 것은 아니며 복잡한 레이아웃 또는 복잡한 기능 포함하고 있다. 안드로이드는 기본적인 간단한 Dialog를 버튼들을 제공하고, Dialog 레이아웃은 마음대로 바꿀 수 있다. base 클래스는 Dialog이며 dialog box를 열 수 있는 helper 메소드는 Activity.showAlert()로 조작이 가능하다.
 
Window
look and feel, 위치, 메뉴의 내용등과 같은 일반적인 창 요소들을 정의할 수 있는 추상 클래스이다. Dialog와 Activity는 이 클래스의 구현을 사용하여 윈도우를 그리며, 이 클래스를 별도로 구현할 필요는 없다.
 
Surface
화면에 대응되는 복합적인 엘리먼트에 대한 블록 메모리를 말한다. Surface는 화면상에 그리기를 위해 Canvas 객체를 가지고 있으며 레이어와 표면을 리사이즈 하기 위한 다양한 helper 메소드를 제공한다. 이 클래스를 직접 사용할 수는 없고 SurfaceView를 사용하면 된다.
 
SurfaceView
화면에 그리기를 위한 Surface의 Wrapper View 객체이며, 사이즈와 포맷을 다양하게 조절할 수 있는 메소드를 포함하고 있다. 카메라 애플리케이션에서 미리보기를 위해 SurfaceView를 사용한다. SurfaceView는 게임이나 카메라 미리보기와 같은 리소스를 차지하는 UI 스레드와는 독립적으로 그리는 방법을 제공하지만 추가적인 메모리를 요구한다. SurfaceView는 Canvas와 OpenGL ES 그래픽을 동시에 지원한다.
 
Canvas
실제적인 비트들이 복합되어져 그리는 것이다. 이것은 bitmap, line, circle, rectangles, text등의 표준 그리기 메소드를 제공하며 Bitmap 또는 Surface에 적용할 수 있다. Canvas는 2D 객체를 가장 간단하고 쉬운 방법으로 화면에 그릴 수 있도록 한다. 그러나 OpenGL ES와 같이 하드웨어 가속 같은 것은 제공하지 않는다.
 
OpenGL ES
안드로이드는 빠르고, 복잡한 3D 이미지를 위해 OpenGL ES 라이브러리를 제공한다. 이것은 Canvas 객체보다 사용하기가 더 어렵지만, 3D 객체에 대해서는 훨씬 더 좋다. graphics.glutils 패키지에 OpenGL ES 기능이 포함되어 있다.

 

 

 

 

 

 

 

[출처] http://www.kandroid.org/

안드로이드 UI 구현 - 화면 구성요소들의 계층구조

안드로이드 UI 구현 - 화면 구성요소들의 계층구조


안드로이드 애플리케이션의 가장 기본적인 기능 단위는 Activity(android.app.Activity 클래스의 객체)이다. Activity는 아주 많은 것을 할 수 있지만 Activity 그 자체만으로는 화면상에 아무것도 보여지지 않는다. Activity가 UI를 화면상에 나타내기 위해서는 안드로이드 플랫폼에서 사용자 인터페이스를 표현하는 기본 단위인 View와 ViewGroup과 함께 사용되어야 한다. 여기서는 각 화면 구성요소에 대한 간략한 설명을 하고, 추후에 필요에 따라 각 구성요소를 자세하게 설명하도록 하겠다.
 
(1) View
View는 android.view.View base 클래스의 객체이다. 이것은 화면상에서 특정한 직사각형 영역의 레이아웃과 내용을 저장하는 자료 구조이다. View 객체는 화면상의 특정 영역내에서 정렬, 레이아웃, 그리기, 포커스 이동, 스크롤링, 키 등을 다룬다.
View 클래스는 위젯(widget : 상호작용하는 화면 요소를 그리도록 구현된 서브 클래스를 말함)을 위한 base 클래스이다. 위젯은 자신만의 영역과 화면상에 보여지는 그래픽 요소를 가지고 있으며, 위젯을 이용하여 UI를 빠르게 만들어낼 수 있다. 위젯에는 Text, EditText, InputMethod, MovementMethod, Button, RadioButton, Checkbox, ScrollView 가 있다.
 
(2) ViewGroup
Viewgroup은 android.view.Viewgroup 클래스의 객체이다. 이 클래스의 이름이 말해주듯이 자신이 포함하는 하위의 View와 ViewGroup을 제어하는 기능을 가진 Composite 패턴의 특별한 View Object이다. Viewgroup은 UI의 구조를 만들어주고, 복잡한 화면 요소들을 만들어 하나의 엔티티로 취급할 수 있도록 한다. Viewgroup 클래스는 레이아웃(layout : 화면 레이아웃의 공통적인 틀을 제공할 수 있도록 구현된 클래스)의 base 클래스이다.
 
(3) Tree-Structured UI
안드로이드 플랫폼에서는 아래와 같은 다이어그램처럼 View와 Viewgroup 노드의 트리구조를 사용하여 Activity의 UI를 정의할 수 있다. 어떻게 구성하느냐에 따라 트리는 간단할 수도 복잡할 수도 있고, 안드로이드에서 제공하는 위젯과 레이아웃 또는 직접 제작한 view를 이용하여 이를 구성할 수 있다.
 
<그림1>

이러한 트리 구조를 화면상에 그려주기 위해서는 Activity가 setContent() 메소드를 호출하고 root 노드 객체를 이 메소드에 넘겨주면 된다. Activity가 활성화 되고 포커스를 받으면, 시스템은 Activity에 root 노드를 통해 화면상에 그리는 것을 요청하게 되며, root 노드는 하위의 노드를 그릴 것을 요청한다.
각 Viewgroup은 가용한 공간을 계산하고, 그 하위의 View를 배치하며 각 하위의 View에서 Draw() 메소드를 호출하여 스스로 그릴 수 있도록 한다. 각 하위의 View는 사이즈와 그려질 위치를 부모로부터 요청하며, 부모는 최종적으로 얼마나 크게, 어디에 그려질 수 있는가를 결정한다.
 
(4) LayoutParams: 어떻게 하위의 View가 위치와 사이즈를 결정하는가?
모든 Viewgroup 클래스는 ViewGroup.LayoutParams를 확장한 클래스를 이용한다. 이 서브클래스는 하위의 View 사이즈와 위치, Viewgorup 클래스의 특성들을 포함하고 있다.
모든 LayoutParmas의 서브클래스는 값을 설정하는 각자의 방법을 가지고 있다. 각 하위 요소들은 반드시 부모의 특징에 맞는 LayoutParams를 정의해야 한다.
 
<그림2>
모든 Viewgroup은 가로(width)와 세로(height), 마진(margin), 테두리(border)를 가지고 있으며 이를 사용자가 원하는 크기로 바꿀 수 있다.

 

 

 

 

[출처] http://www.kandroid.org/

 

 

안드로이드 애플리케이션 Life Cycle

안드로이드 애플리케이션 Life Cycle


♦ 안드로이드 애플리케이션 Life Cycle
대부분의 경우에 안드로이드 애플리케이션은 자신 고유의 리눅스 프로세스에 의해 실행된다. 이 프로세스는 애플리케이션이 특정 코드를 수행할 필요가 있을 때 생성되고, 시스템이 다른 애플리케이션에 사용할 메모리를 요청 또는 더 이상 필요없어질 때까지 실행 상태를 유지한다.
안드로이드의 중요한 특성은 애플리케이션의 프로세스 Life Cycle은 애플리케이션 자신에 의해 직접 컨트롤되지 않는다는 것이다. 그것은 시스템이 실행상태를 알고 있는 애플리케이션 부분들의 조합(얼마나 사용자에게 중요한 것인가, 시스템의 여유 메모리가 얼마나 더 남아있는가)으로 결정된다.
애플리케이션 개발자들이 알아야 할 중요한 사항은 어떻게 서로 다른 애플리케이션 컴포넌트(Activity, Service, IntentReceiver)들이 애플리케이션의 프로세스에 영향을 미치는가 하는 것이다. 이러한 컴포넌트들을 정확하게 사용하지 않을 경우, 시스템은 중요한 일을 하고 있는 애플리케이션의 프로세스를 종료시킬 수 있다.
프로세스 lifecycle 버그의 일반적인 예는 onReceiveIntent() 메소드 내에서 Intent를 받고 함수에서 리턴될 때, IntentReceiver가 스레드를 시작하는 것이다. 한번 리턴되고 나면 시스템은 IntentReceiver를 비활성 상태로 인식하게 되고, 그것을 실행하는 호스팅 프로세스는 다른 애플리케이션 컴포넌트가 그 안에서 활성화 되어 있지 않는 한 필요없어지는 것이다. 그러므로 메모리 요청에 의해 언제든지 프로세스가 종료될 수 있고, 생성되어 실행되던 스레드도 종료된다. 이 문제의 해결법은 IntentReceiver로부터 Service를 실행하는 것이다. 그래서 시스템이 그 프로세스를 종료하기전에 여전히 어떤 작업이 활성화 되어 있음을 인식하게 하는 것이다.
유휴 메모리가 부족할 때 어떤 프로세스가 종료되어야 하는지 결정하는 것은 중요한 것이다. 안드로이드는 이것을 “importance hierarchy”를 베이스로 하고, “Importance hierarchy”내에서 실행중인 컴토넌트와 그 컴포넌트들의 상태에 따라 결정한다. 중요도의 순서는 다음과 같다.


 

(1) foreground process : 사용자가 조작중인 최상위 화면의 Activity(onResume() 메소드가 호출된 경우) 또는 현재 실행중인 IntentReceiver(onReceiveIntent() 메소드가 실행중)를 잡고 있는 프로세스이다. 시스템에는 아주 적은 수의 이런 프로세스가 있고, 이러한 프로세스가 실행되기에 극히 부족한 메모리가 있을 경우에만 종료된다. 이러한 동작은 일반적으로 기기가 메모리 페이징 상태에 다다랐을 때이며, 사용자 인터페이스 응답을 유지하기 위해서 취해진다.


(2) visible process : 사용자 화면에는 보여지지만 foreground는 아닌(onPause() 메소드를 호출한 경우) Activity를 잡고 있는 프로세스이다. 예를 들면 foreground activity가 다이알로그를 보여주며 이전 activity는 그 아래에 위치하는 것과 같다. 이런 프로세스는 매우 중요하며, 모든 foreground 프로세스 실행이 종료되기 전까지는 종료되지 않는다.


(3) service process : startService()를 호출한 Service를 잡고 있는 프로세스이다. 이러한 프로세스는 사용자에게 직접적으로 보여지는 것은 아니지만 사용자와 관련된 일반적인 일(mp3를 배경음으로 연주한다던가, 네트워크 데이터를 업로드/다운로드 한다던가 하는등)들을 한다. 그래서 이러한 프로세스는 모든 foreground, visible 프로세스를 유지하기에 메모리가 충분하지 않을때까지 계속 유지된다.


(4) background process : 사용자에게 현재는 보여지지 않는 activity(onStop() 메소드를 호출한 경우)를 잡고 있는 프로세스이다. 이런 프로세스들은 사용자에게 어떠한 영향을 주지 않으며, activity lifecycle을 정확하게 구현하기 위해서 제공된다. 시스템은 메모리가 부족할 경우 언제든지 이런 프로세스 수행을 멈출 수 있다. 가끔식 이러한 프로세스들이 많이 수행되고 있을 때, 메모리 부족시 가장 최근에 사용자에게 보여진 것이 가장 마지막으로 종료되도록 LRU 목록에 유지된다.


(5) empty process : 어떠한 활성화된 애플리케이션 컴포넌트들도 잡고있지 않는 프로세스이다. 이러한 프로세스를 유지하고 있는 이유는 다음에 컴포넌트의 애플리케이션이 시작되어야 할 때 시작 시간을 개선하기 위한 캐시로 사용하기 위해서다. 시스템은 캐쉬된 빈 프로세스와 커널 캐쉬 사이의 시스템 전체 리소스의 균형을 맞추기 위해 이런 프로세스를 종료시킨다.


 

시스템이 프로세스를 구별하기 위해 현재 활성화된 프로세스중에 가장 중요한 레벨을 가지는 모든 컴포넌트들을 찾아낸다. 안드로이드 애플리케이션 lifecycle에 대해서는 Activity, Service, IntentReceiver에 대해 자세히 얘기할 때 이러한 컴포넌트들이 어떻게 프로세스의 전체 lifecycle에 영향을 미치는지 알아보도록 하겠다.

 

[출처] http://www.kandroid.org/