
자바 5.0 이상
JDK 5 또는 6이 필요하다.
자바 실행시간 개발 환경(JRE:Java runtime environment)만으로는 충분하지 않으며 전체 개발 킷을 사용한다. 썬사의 다운로드 사이트(http://java.sun.com/javase/downloads)에서 JDK 6.0의 최신 업데이트를 받는다.
올바른 버전인지 확인하려면 셸 창에서 아래의 명령어를 실행하자. 다음과 같은 정보가 출력된다.
C:\> java -version
java version "1.6.0_02"
Java(TM) SE Runtime Environment ( build 1.6.0_02-b05 ) -- 버전이 '1.6' 이상이어야 한다.
이클립스
사용 가능한 이클립스 최소한의 버전은 3.3.1 이지만, 될 수 있는 한 항상 최신 버전을 사용한다. 이클립스 SDK는 기본 '클래식' 플랫폼 이상이 필요하다.
안드로이드
구글에서 최신 안드로이드 SDK를 다운로드하자. 안드로이드 다운로드 페이지(http://code.google.com/android)는 윈도우, 맥 OS X 및 리눅스 운영체제용 패키지를 제공한다. 다운로드가 끝나면 C:\Google과 같이 편리한 디렉토리에 압축 파일(.zip)을 풀어 놓는다.
기본적으로 SDK는 androidsdk-windows-1.1_r1(2009.2.23 기준)과 같은 하위 디렉토리로 확장되는데, 이것이 SDK 설치 디렉토리 이므로 나중에 참조할 수 있도록 전체 경로를 기억해 두자.
이클립스 플러그인
구글은 이클립스의 개발 편이를 위해 안드로이드 개발 툴킷(ADT : Android Development Toolkit)이라는 플러그인을 만들었다. 이 플러그인의 설치 순서는 다음과 같다(이 순서는 이클립스 버전 3.4를 기준으로 하므로, 다른 버전을 이용할 경우 메뉴나 옵션이 조금 다를 수도 있다).
1. 이클립스를 시작해 '도움(Help)'을 선택한 후, '소프트웨어 업데이트(Software Updates)'를 선택한다.
2. '사용 가능한 소프트웨어(Available Software)' 탭이 선택되어 있지 않다면 클릭한다.
3. '사이트 추가하기(Add Site)' 버튼을 누른다.
4. 안드로이드 업데이트 사이트 주소 https:://dl-ssl.google.com/android/eclipse/를 입력한다. < 오류창 뜨면 https를 http로 고치고 다시 시도해 본다 >
5. '사용 가능한 소프트웨어' 뷰에 '안드로이드' 사이트가 이제 나타난다. 옆에 보이는 체크박스를 선택한 후, '설치하기(Install)'를 클릭한다. 올바른 이클립스 버전이 깔려 있지 않다면 오류 메시지가 나온다. 자바용 또는 자바 EE용으로 미리 만들어진 이클립스 IDE 개발 패키지 버전 3.4 이상을 사용하도록 적극 권한다.
이클립스를 사용자 지정 방식으로 설치한 후, 안드로이드 에디터를 사용하려면 웹 스탠더드 도구(WST:Web Standard Tools) 플러그인과 필수 구성요소를 추가로 설치한다.
자세한 사항과 다운로드 링크는 웹 도구 플랫폼(Web Tools platform) 홈페이지(http://www.eclipse.org/webtools)를 참고해 보기 바란다. 다운로드 추천 패키지에는 이러한 요소들이 이미 내장되어 있다.
6. '마침(Finish)'을 누르면 다운로드와 설치가 진행된다.
7. 설치가 끝나고 나면 이클립스를 다시 시작한다.
8. 이클립스가 다시 시작하고 나면 오류 메시지가 나타나는데 안드로이드 SDK가 어디 있는지 알려줘야 한다. 'Windows > Preferences > Android'에 가서 미리 적어놓은 SDK 설치 디렉터리 주소를 입력한 후, 'OK'를 누른다.
'연결 오류(connection error)'라고 나오는데 어떻게 해야 하나요?
연결 오류가 발생하는 가장 흔한 원인은 시스템 관리자가 만든 방화벽이다. 방화벽을 벗어나려면, 이클립스에 프록시 서버 정보를 구성해야 한다. 이클립스에 프록시 설정을 하려면 'WIndows > Preferences > Network Connections'을 선택한 후, 'Manual Proxy Configuration' 옵션을 선택하고, 서버 이름과 포트 넘버를 입력한 후 'OK'를 클릭한다.
SDCard 생성하기
안드로이드 에뮬레이터에서 사용자가 임의로 파일을 저장하려면 안드로이드 에뮬레이터에 가상의 SD카드가 마운트 되어 있어야 합니다. 가상 SD카드를 생성하려면 안드로이드 SDK폴더\tools 폴더의 mksdcard.exe 을 이용하면 됩니다.
실행-cmd를 입력하여 명령 프롬프트 창을 열고, 안드로이드 sdk가 설치된 폴더\tools폴더에 간 후, mksdcard [용량] [파일명] 을 입력하여 가상의 SD카드를 만듭니다.
가상 SD카드 파일도 만든 후 에뮬레이터에 마운트 시켜야 합니다. 설정은 Run -> Run Configurations -> Target 탭의 Additional Enulator Command Line Options에 넣어주면 됩니다
안드로이드 SDK 1.5용 AVD(Android Virtual Device) 생성하기
이클립스에 Window -> Android AVD Manager 클릭합니다.
위와 같이 AVD Manager가 표시됩니다. 아래의 Create AVD 항목을 이용하여 AVD를 생성합니다. Name 항목은 다른 이미지와 구분을 가도록 지어주면 됩니다. Target에서는 Android 1.5를 선택합니다. SDCard는 생성한 가상 SD카드의 경로를 입력하면 됩니다. Create AVD 버튼을 누르면 완료됩니다.
첫 프로그램
ADT에서 기존 제공되는 예제 프로그램을 사용해 간단한 'Hello, Android' 프로그램을 만들어 보자.
'File -> New File -> Android Project'를 선택해 'New Project'창을 연다. 그리고는 'Android -> Android Project -> Next'을 누른 후 아래 정보를 입력한다.
Project name : Hello
Package name : org.example.hello
Activity name : Hello
Application name : Hello, Android
모든 정보가 입력되면 다음과 같은 창을 볼 수 있다.
'마침(Finish)'을 누르면 안드로이드 플러그인이 프로젝트를 만들고 기본 파일을 채워 넣으며, 이클립스가 이를 구성하고 설계해 실행 가능하게 만든다.
에뮬레이터에서 실행하기
안드로이드 프로그램을 실행하려면, 패키지 익스폴로러(Package Explorer)창의 'Hello, Android' 프로젝트 위에서 오른쪽 마우스 버튼을 클릭한 후, '다른 이름으 실행하기(Run As) -> 안드로이드 애플리케이션'을 선택한다.
소모 줄이기
에뮬레이터를 실행하는 데는 시간이 많이 걸린다. 그러므로 이클립스가 실행되고 있는 한 에뮬레이터를 끄지 말고, 창을 계속 실행시킨다. 그러면 다음번 안드로이드 프로그램이 시작할 때, 이클립스는 에뮬레이터가 이미 열려 있으니 이를 다시 시작하지 않고 새 프로그램만 열어준다.
실제 핸드폰에서 실행시키기
T-Mobile G1과 같은 실제 장치에서 안드로이드 프로그램을 실행해 보는 것은 에뮬레이터에서 실행하는 것과 유사하다. 폰은 USB 케이블로 연결한 후 특정 장치 드라이버(http://developer.android.com/index.html)를 설치하면 된다. 에뮬레이터 창이 이미 열려 있다면 닫는다. 폰이 연결되어 있으면 애플리케이션은 로딩되어 폰에서 실행된다.
애플리케이션을 공개할 준비가 되면, 암호키를 받아 패키지 서명에 사용한다. 이 작업을 하는 방법은 온라인에 나와 있다. 소정의 등록비를 내면 안드로이드 마켓에 자신의 프로그램을 업로드할 수 있다(http://www.android.com/market/).
안드로이드 시스템 아키텍쳐
각 층은 그 바로 아래 계층에서 제공하는 서비스를 사용한다.
리눅스 커널
안드로이드는 내부의 메모리 관리, 프로세스 관리, 네트워킹, 운영체제 시스템 서비스등에 리눅스를 사용한다. 안드로이드 폰 사용자에게 리눅스는 보이지 않으며, 여러분이 만든 프로그램 또한 리눅스를 직접 호출하지는 않지만, 개발자라면 리눅스가 사용되고 있다는 사실 정도는 알아야 한다.
내장 라이브러리
이 공유 라이브러리는 C 또는 C++ 로 쓰여 있고 핸드폰에 사용되는 특정 하드웨어를 위해 컴파일되어 핸드폰 공급업체에 의해 폰에 미리 설치된다.
가장 중요한 라이브러리는 다음과 같다.
서피스 매니저(surface manager) : 안드로이드는 비스타와 비슷하지만 훨씬 간단한 복합 윈도 매니저를 사용한다. 그리기 명령어는 스크린 버퍼에 직접 그리지 않고 오프 스크린 비트맵을 기친 뒤, 다른 비트맵과 합쳐져 사용자가 볼 화면을 만들어낸다.
2D와 3D 그래픽 : 안드로이드에서는 2차원 요소와 3차원 요소가 하나의 사용자 인터페이스에서 결합될 수 있다. 라이브러리 장치에 3D 하드웨어가 있으면 이를 사용하고, 없으면 빠른 소프트웨어 렌더러를 사용한다.
미디어 코덱 : AAC, AVC(H.264), H.263, MP3, MPEG-4 등의 다양한 포맷을 지원한다.
SQL 데이터베이스 : 경량의 SQLite 데이터베이스 엔진(http://www.sqlite.org)을 갖추고 있다. 만들 애플리케이션에 지속적인 정보 저장이 필요하다면 이것을 사용한다.
브라우저 엔진 : HTML 콘텐츠를 신속하게 디스플레이하기 위해 안드로이드는 WebKit 라이브러리(http://www.webkit.org)를 사용한다.
안드로이드 런타임
달빅(Dalvik) VM과 코어 자바 라이브러리 등이 포함된다. 달빅 VM은 모바일 디바이스용으로 최적화해 구현된 구글의 자바 격이다. 여러분이 안드로이드용으로 쓰는 모든 코드는 자바로 작성되며 VM 내에서 실행된다.
달빅은 전형적인 자바에 대비해 다음과 같은 중요한 두 가지 중요한 차이점이 있다.
달빅 VM은 .dex 파일을 실행시키는데 이 파일은 표준 .class와 .jar 파일이 컴파일 시점에 변환된 것이다. .dex 파일은 클래스 파일보다 콤팩트하고 효휼성이 높기 때문에 안드로이드가 사용될 적은 메모리와 배터리로 작동하는 환경에 적합하다.
안드로이드에 들어 있는 코어 자바 라이브러리는 자바 스탠더드 에디션 라이브러리와 자바 모바일 에디션 라이브러리와는 다르지만 중복되는 부분이 상당히 있다.
애플리케이션 프레임워크
애플리케이션을 만들 때 사용될 높은 수준의 빌딩 블록이 여기에서 제공된다. 이 프레임워크는 안드로이드에 미리 설치되어 있는데 필요하다면 여러분이 만든 컴포넌트를 가지고 확장시킬 수 있다. 프레임워크의 가장 중요한 부분은 다음과 같다.
액티비티 매니저(activity manager) : 애플리케이션의 생명주기를 제어하고 사용자 내비게이션을 위해 '백스택(Back-stack)'을 유지한다.
콘텐츠 제공자(content provider) : 이 객체들은 주소록과 같이 애플리케이션 사이에서 공유되는 정보를 요약한다.
리소스 매니저(resource manager) : 리소스란 프로그램의 코드 외 모든 부분이다.
위치 매니저(location manager) : 안드로이드 폰은 항상 자신의 위치를 파악하고 있다.
알림 매니저(notification manager) : 도착 메시지, 약속, 근접성 알림 등의 사건은 사용자에게 방해되지 않는 방식으로 전달될 수 있다.
애플리케이션
최종 사용자는 수위선 아래에서 일어나는 모든 작업을 알지 못하면 오직 이 애플리케이션만을 보게 된다. 안드로이드 폰을 구입하면 다음의 기본 시스템 애플리케이션이 미리 설치되어 제공된다.
전화 다이얼 장치, 이메일, 주소록, 웹 브라우저, 안드로이드 마켓
안드로이드는 고유한 작동 방식을 갖고 있다.
안드로이드는 포어그라운드 애플리케이션이 하나며, 상태 줄을 제외한 전체 스크린을 차지한다.
사용자가 애플리케이션을 실행시키면 안드로이드는 그 프로그램을 시작한 후, 포어그라운드에 놓는다. 거기에서 사용자는 다른 애플리케이션을 호출하거나 같은 애플리케이션 내의 다른 화면을 호출한다. 이 모든 프로그램과 화면은 시스템의 액티비티 매니저에 의해 애플리케이션 스택에 기록된다. 아무 때고 '이전(Back)' 버튼을 누르면 스택에 저장된 이전 화면으로 이동한다.
프로세스는 애플리케이션과 다르다.
내부적으로 보면 개별 사용자 인터페이스 화면은 Activity 클래스에 의해 표현된다. 액티비티는 각기 생명주기를 갖고 있다. 애플리케이션은 한 개 이상의 액티비티에 이것을 담을 리눅스 프로세스를 합친 것인데, 간단해 보이지만 아직 안심하면 안 된다. 주의할 점이 있다.
안드로이드상에서, 애플리케이션은 해당 프로세스가 죽여졌을 때조차도 살아 있을 수 있다. 다시 말해 액티비티의 생명주기가 프로세스의 생명주기와 긴밀하게 결합되어 있지 않다. 프로세스란, 액티비티를 자유롭게 담을 수 있는 그릇, 즉 컨테이너이다.
액티비티 생명주기
안드로이드 프로그램의 각 액티비티는 생명주기 동안 밑의 그림의 여러 상태 중 하나에 놓인다. 프로그램이 어느 상태에 놓여 있는지는 개발자가 조정할 수 없으며 시스템에 의해 관리된다. 하지만 여러분은 상태가 변경되었을 때 onXX()메서드가 호출되는 방식으로 알 수 있다.
여러분이 Activity 클래스에서 해당 메서드를 오버라이드(override)하면, 안드로이드는 이를 적당한 시기에 호출할 것이다.
OnCreate(Bundle) : 액티비티가 처음 시작할 때 호출된다. 사용자 인터페이스를 만드는 등의 일회적 초기화 실행에 사용된다. onCreate()는 널(null) 값 또는 onSaveInstanceState() 메서드에 의해 저장된 상태 정보 중 한 가지의 매개변수를 갖는다.
onStart() : 액티비티가 사용자에게 곧 보여질 것임을 나타낸다.
onResume() : 액티비티가 사용자와 상호작용을 시작할 수 있을 때 호출된다. 애니메이션과 음악을 시작하기에 좋은 곳이다.
onPause() : 액티비티가 배경으로 전환될 때 실행되는데, 주로 다른 액티비티가 이 프로그램 앞에 놓이게 됨으로써 일어난다. 데이터베이스 기록 수정 등 프로그램의 지속적 상태 정보를 이곳에 저장해 놓는다.
onStop() : 액티비티가 사용자에게 더 이상 보여지지 않을 때 호출되며, 액티비티는 한동안 사용되지 않는다. 메모리가 얼마 남지 않았다면 onStop()은 호출되지 않고 시스템이 프로세스를 종료해 버릴 수 있다.
onRestart() : 이 메서드가 호출되면 여러분의 액티비티가 정지 상태에서 다시 디스플레이된다.
onDestory() : 액티비티가 소멸되기 직전에 호출된다. 메모리가 얼마 남지 않았다면 onDestory()는 호출되지 않고 시스템이 프로세스를 종료해 버릴 수 있다.
onSaveInstanceState(Bundle) : 텍스트 필드 내의 커서 위치 등의 인스턴스별 상태를 액티비티가 절약하도록 이 메서드가 호출된다. 디폴트 구현 값이 모든 사용자 인터페이스 제어 상태를 자동으로 저장하므로 대개 재정의할 필요 없다.
onRestoreInstanceState(Bundle) : onSaveInstanceState() 메서드가 미리 저장해 둔 상태로부터 액티비티가 다시 초기화될 때 호출된다. 디폴트 구현 값이 여러분 사용자 인터페이스 상태를 복원한다.
안드로이드 SDK에 정의된 객체 중 모든 개발자가 알아야 할 몇 가지가 있다. 그중 가장 중요한 것은 액티비티, 인텐트, 서비스 그리고 콘텐츠 제공자다.
액티비티
액티비티란 사용자 인터페이스 화면을 일컫는다. 애플리케이션은 프로그램의 여러 단계를 다루기 위해 한 개 이상의 액티비티를 정의한다.
인텐트
인텐트란 '사진을 집어들다', '집에 전화 걸다'와 같은 구체적인 행동을 설명하는 메커니즘이다. 안드로이드에서 거의 모든 것이 인텐트를 거치므로 구성요소를 대체하거나 재사용할 수 있게 해 준다.
서비스
서비스란 유닉스 데몬처럼 사용자와의 직접적인 상호작용 없이 배경에서 실행되는 작업이다. 예를 들어 오디오 플레이어를 생각해 보자. 음악은 액티비티에 의해 시작되며 사용자가 다른 프로그램으로 옮겨가도 계속해서 제생된다. 그렇기 때문에 실제 재생을 담당하는 코드는 '서비스'로 되어 있어야 한다.
콘텐츠 제공자
콘텐츠 제공자란 데이터의 읽기와 쓰기를 위해 데이터가 사용자 API로 포장된 것이다. '애플리케이션 사이에서' 전역으로 데이터 공유를 하는 최선책이다.
리소스란 프로그램에 필요한 지역화된 텍스트와 비트맵 등 코드 외의 작은 정보다. 안드로이드 리소스 컴파일러는 파일이 어느 하위 디렉토리에 있는지와 파일이 형식에 따라 처리한다. 예를 들어 PNG와 JPG 형식의 비트맵은 res/drawable 디렉터리에 놓아야 하며 화면 레이아웃을 설명하는 XML 파일은 res/layout 디렉터리에 놓여야 한다.
리소스 컴파일러는 리소스를 압축하고 묶어서 R이라는 클래스를 생성하는데, R 클래스는 프로그램에 있는 리소스 참조에 사용되는 식별자를 갖고 있다.
애플리케이션은 개별 리눅스 프로세스 내에서 실행된다. 하드웨어는 한 프로세스가 다른 프로세스의 메모리에 액세스하는 것을 막는다. 각 애플리케이션은 사용자 ID를 할당받는데 한 애플리케이션이 만든 파일은 다른 애플리케이션이 읽거나 쓸 수 없다. 애플리케이션이 일부 중요한 작업에 액세스하는 것은 제한되며 AndroidManifest.xml 파일 안에서 사용하려면 따로 허가를 받아야 한다. 애플리케이션이 설치되면 패키지 매니저가 인증에 따라 권한을 허가하거나 제한하는데, 필요 시에는 사용자가 확인할 수 있다. 가장 흔히 사용될 권한 몇 가지를 보자.
INTERNET : 인터넷 액세스하기
READ_CONTACTS : 사용자의 주소록 정보 읽기(쓰기는 아님)
WRITE_CONTACTS : 사용자의 주소록 정보 쓰기(읽기는 아님)
RECEIVE_SMS : 수신 메시지 모니터링하기
ACCESS_COARSE_LOCATION : 셀 타워나 와이파이(WIFI)등 하등의(조잡한) 위치 제공자 사용하기
ACCESS_FINE_LOCATION : GPS 등의 정교한 위치 정보 제공자 사용하기
사용자 인터페이스는 절차적 또는 선언적 방식으로 디자인될 수 있다. 절차적이란 코드에 비롯한다는 뜻이다. 반면에, 선언적 디자인은 코드를 통해 구현하지 않는다. 간단한 웹 페이지를 만든다면 HTML을 사용하는데, HTML은 XML에 기초한 생성 언어로 페이지가 어떻게 작동하는지가 아니라 무엇을 나타내는지를 선언한다. 그러므로 HTML은 선언적이다.
둘 모두 유효한 방식이지만 될 수 있는 한 선언적인 XML을 사용하도록 권한다. XML 코드는 자바 코드에 비해 짧고 이해가 쉽기 때문에 GUI 디자이너등, 앞으로 안드로이드용으로 개발될 도구가 작업하기 쉬운 여건을 만들어 준다.
프로젝트를 새로 만들고 다음 값을 입력한다.
Project name : Sudoku
Package name : org.example.sudoku
Activity name : Sudoku
Application name : Sudoku
이 상태에서 프로그램을 실행하면 'Hello World, Sudoku!'라는 문구만 보이는 빈 화면이 나타난다. 여기서 첫 번째로 해야 할 일은 이 화면을 게임의 오프닝 화면으로 바꾸는 것이다.
2장 "주요 개념"에서 언급했듯이 안드로이드는 액티비티가 느슨하게 연결된 집합인데, 개별 액티비티가 사용자 인터페이스 화면을 각기 정의한다. 스도쿠 프로젝트가 만들어지면 안드로이드 플러그인이 Sudoku.java 파일 내에 한 액티비티를 만든다.
안드로이드는 액티비티에서 onCreate() 메서드를 호출해 초기화한다. setContentView()를 호출하면 안드로이드 뷰 위젯이 액티비티 화면의 콘텐츠를 채운다.
위의 R.layout.main은 res/layout 디렉터리 안의 main.xml 파일을 호칭하는 리소스 식별자다. XML에서 사용자 인터페이스를 선언하는 main.xml 파일이 우리가 수정해야 할 파일이다. 실행이 되면, 안드로이드는 그 파일에 정의돼 있는 리소스의 구문을 분석(파싱)하고 인스턴스화(팽창)해 현 액티비티의 뷰(보기)로 설정한다.
R 클래스는 안드로이드 이클립스 플러그인에 의해 자동적으로 관리됨을 기억한다. res 디렉터리에 파일을 놓으면 플러그인은 변화를 알아채고 R.java에 리소스 ID를 저장한다. 리소스 파일을 없애거나 수정하면, R.java 또한 동기화된다. 에디터에서 파일을 열면 다음과 유사한 코드를 볼 수 있다.
패키지 내의 컴파일된 실제 데이터와 문자열, 그 외 자산(asset)등을 불러올 때 안드로이드 리소스 관리자는 16진수 숫자를 사용한다. 자세한 값에 대해선 신경 쓰지 않아도 된다.
이제 main.xml을 수정할 차례다. 이클립스의 main.xml을 두 번 클릭해 열어 놓는다. 이클립스의 구성에 따라 시각적인 레이아웃 에디터 또는 XML 에디터가 나올 것이다. ADT(안드로이드 개발 도구)의 현 버전에서 시각적 레이아웃 에디터는 그다지 유용하지 않으므로 main.xml이나 하단의 '소스'탭을 클릭해 XML 에디터를 사용한다.
안드로이드가 제공하는 일반적인 레이아웃은 다음과 같다.
FrameLayout : 모든 하위 객체가 화면의 왼쪽 위에서 시작하도록 정렬한다. 탭 뷰와 이미지 전환기에 사용된다.
LinearLayout : 객체를 한 개의 열 또는 행에 정렬한다. 가장 흔히 사용되는 레이아웃이다.
RelativeLayout : 객체를 서로의 관계를 기준으로, 또는 상위 객체와 관계해 정렬한다. 폼에서 자주 사용된다.
TableLayout : HTML 테이블과 유사하게 하위 객체를 열과 행으로 정렬한다.
이 파일을 다른 텍스트와 몇 개의 버튼으로 교체해 보자. 첫 시도는 다음과 같다.
에디터에서 누락된 문법 제약 조건(DTD나 XML 스키마)에 대한 경고가 나오면 무시한다.
영문 텍스트를 레이아웃 파일에 직접 코딩하는 대신 @string/resid 구문으로 res/values/strings.xml 파일 안의 문자열을 참조할 수 있다. 파일을 열고 하단에 있는 strings.xml 탭을 선택해 다음을 입력한다.
다음은 res/values/colors.xml에 들어갈 색상 정의다.
다음은 새로운 레이아웃을 정의한다.
이번 버전에서는 @+id/resid라는 새로운 구문이 나온다. 다른 곳에 정의된 리소스 ID를 참조하는 대신 이곳에 새로운 resid를 만들어 이를 참조한다. 예를 들어, @+id/about_button은 About 버튼의 ID를 정의하는데 이 ID를 이용해 버튼이 눌릴 때의 동작을 정의할 수 있다.
결과 실행 화면은 밑의 그림과 같다.
하지만 가로가 긴 경우는 어떠한가? 사용자는 아무 때나 키보드를 열고 폰을 옆으로 돌려 모드를 바꿀 수 있으므로 방향이 바뀌는 경우를 대비해야 한다.
테스트로 에뮬레이터를 가로 방향으로 전환해 보자(Ctrl+F11 또는 키패드 7 이나 9 누르기).
가로 방향에서는 EXIT 버튼을 볼 수 없다.
레이아웃을 수정해 모든 방향에서 사용 가능하게 만들 수 있지만 종종 수정이 불가능하거나 화면이 어색해지기도 한다. 그러므로 가로 방향 모드를 위한 새 레이아웃을 만들어 보자.
아래의 레이아웃을 가진 res/layout-land/main.xml(-land 접미사 주의하기)파일을 만든다.
이 코드는 TableLayout을 사용해 버튼을 두 개의 열로 만든다. 이제 프로그램을 다시 실행시킨다. 가로 방향 모드에서도 모든 버튼이 보인다.
레이아웃뿐만 아니라 모든 리소스의 대체(alternative) 버전을 명시하는 데도 디렉터리 이름에 리소스 접미사를 사용할 수 있는데, 예를 들어 텍스트를 다른 언어로 로컬라이즈한다면 버전 구분에 언어 접미사를 사용할 수 있다. 각각의 대체 리소스 파일은 동일한 ID 집단을 정의해야 한다.
사용자가 터치 스크린을 통해 About 버튼을 선택하면, 스도쿠에 관한 정보가 있는 창이 나온다. 그 창의 텍스트를 스크롤하다가 사용자는 '이전' 버튼을 눌러 창을 닫는다.
이 작동을 구현하는 몇 가지 방법이 있다.
새 액티비티를 정의하고 시작시킨다.
AlertDialog 클래스를 사용해 보여준다.
하위 클래스인 Dialog 클래스를 새 뷰로 팽창시켜, 이를 보여준다.
이 예제를 위해 새 액티비티를 정의해 보자. 스도쿠 주요 액티비티처럼 About 액티비티 또한 레이아웃 파일이 필요하다. 이 파일을 res/layout/about.xml이라 하자.
이 레이아웃은 가로 세로 방향 모두에서 아무 문제 없이 표현되므로 한 버전만 있으면 된다.
About 대화상자의 제목과 내용 텍스트를 res/values/strings.xml에 추가한다.
about_text 안의 백슬래시(\)는 첫 단어 앞에 빈 공간이 생기는 것을 방지한다.
About 액티비티는 About.java에 정의돼야 하는데 onCreate()를 덮어쓰고 setContentView()를 호출하는 역할만을 한다.
스도쿠 클래스 안의 About 버튼에 지금껏 나온 부분들을 연결시켜야 한다. Sudoku.java에 몇 개의 import를 추가해 보자.
onCreate() 메서드 안에 findViewById()를 호출해 주어진 리소스 ID의 안드로이드 뷰를 찾는 코드와, setOnClickListener()를 호출해 사용자가 뷰를 건드리거나 클릭했을 때 적합한 객체를 작동시키는 코드를 추가한다.
이 작업을 하면서 나머지 버튼도 수정해 보자. R.is.about_button과 같은 상수는 R.java안에 있는 이클립스 플러그인이 res/layout/main.xml 내의 @+id/about_button을 봤을 때 생성된다.
코드는 이를 리시버로 사용한다. Sudoku 클래스에서 OnClickListener 인터페이스를 구현하고 onClick 메서드를 정의하자.
액티비티를 시작하려면 Intent 클래스의 인스턴스를 먼저 만든다. 인텐트에는 시스템에 등록되어 있는 어느 애플리케이션에서나 사용될 수 있는 공개 인텐트와 한 애플리케이션에서만 사용되는 비공개(익명) 인텐트가 있다. 이 예제에서는 후자만 필요하다.
프로그램을 실행시키고 About 버튼을 지금 선택하면 오류가 발생한다.
한 가지 중요한 순서를 빼먹었다. 모든 액티비티는 AndroidManifest.xml에 선언돼야 한다. 파일을 더블 클릭해 열고, 하단에 있는 AndroidManifest.xml 탭을 선택해 XML 모드로 전환하고 첫 번째 <activity>의 닫는 태그 뒤에 <activity> 태그를 하나 더 추가한다.
이제 manifest 파일을 저장하고, 프로그램을 다시 실행한 뒤, About 버튼을 누르면 밑의 그림과 유사한 화면을 볼 수 있다.
.bmp)
테마란 안드로이드 위젯의 룩앤필(look and feel)을 덮어쓰기 하는 스타일이다. res/values/styles.xml에서 사용자 정의 테마를 만들 수도 있지만 이번 예제에서는 이미 정의된 테마를 사용해 본다. AndroidManifest.xml 에디터를 다시 열고 About 액티비티의 정의를 수정해 테마 속성을 갖게 만든다.
스타일 이름 앞에 붙는 @android: 접두사는 여러분의 프로그램 안에 정의된 리소스가 아닌 안드로이드가 정의한 리소스를 참조한다는 의미를 지닌다.
이제 프로그램을 실행시키면 About 상자는 밑의 그림과 비슷한 모습을 보인다.