예제를 풀다보니 스피너나 메뉴 부분을 할 때는 arrays.xml을 사용하고 ListView나 Adapter에서는 내부 코드에서 ArrayList를 생성해 사용하게된다. 그래서 왜 이렇게 딱 구분해서 사용을 하는걸까 하고 의문을 가지고있었는데, java코드에서 xml 데이터의 조작이 어렵다는 것을 알게되었다. 물론 읽는 것은 가능하지만 xml데이터의 내용을 수정하거나 삭제하는 일은 할 수 없는 것이다. 그래서 동적인 화면을 구성할 때는 arrays.xml파일에 직접 접근하지 않고, 리소스파일을 코드 내의 배열에 옮겨와 작업을 해야한다. 아래는 그 방법이다.

Resources res = getResources();
String[] temp= res.getStringArray(R.array.colors);
arrays.xml에서 colors의 이름을 갖는 배열을 코드상의 temp배열에 옮긴 것이다. 이후 자유롭게 사용이 가능 하겠다.
 기존에 자바를 공부하면서 GUI에 대한 작업은 그렇게 많이 하지 않았기 때문에 이벤트 핸들러 부분에 대해서는 안드로이드를 공부하면서 더 자세히 알게 된 것 같다. 이벤트를 처리하기 위해서는 특정 이벤트에 대해 정의된 콜백 메서드를 사용하여 처리할 수 있는데 여기서 콜백 메서드란 특정 이벤트가 발생하였을 때 시스템에 의해서 자동으로 호출 되는 메서드를 말한다. 다음의 4가지의 콜백 메서드가 안드로이드에서 사용되는 가장 대표적인 것이다.
 boolean onTouchEvent(MotionEvent event)  화면을 터치할 때 발생
 boolean onKeyDown(int keyCode, KeyEvent event)  입력장치(키보드)를 눌렀을 때 발생
 boolean onKeyUp(int keyCode, KeyEvent event)  입력장치(키보드)를 눌렀다 떼었을 때 발생
 boolean onTrackballEvent(MotionEvent event)  트랙볼에 움직임이 발생했을 때 발생
 위의 콜백 메서드 모두 View 클래스로부터 상속받아 재정의 하여 이벤트 발생시의 처리내용들을 정의 할 수 있다. 위의 콜백 메서드의 파라미터인 event파라미터로 이벤트에 대한 상세정보들을 얻을 수 도 있다. 아래의 코드는 바로 View의 onTouchEvent 콜백 메서드를 사용한 것이다. 
 콜백 메서드를 사용하기 위해서는 항상 super클래스를 상속받아 재정의 해야 하는 번거러움이 생기게된다. 자주 발생하는 이벤트야 상관 없다 하여도 안드로이드에서 사용할 수 있는 이벤트의 종류느 매우 많다. 이를 모두 상속받아 재정의 하기 보다는 좀 더 범용적이고 간편한 방법으로 나온 것이 바로 이벤트리스너(Listener)를 사용하는 방법이다.

 다음 코드는 간단하게 버튼 하나를 클릭 했을 때 OK라는 메세지를 출력 할 수 있도록 이벤트 리스너를 등록 하는 것이다.
 리스너 객체를 생성하고 이를 set이벤트리스너()를 이용하여 이벤트 핸들러를 등록 시키는 방식으로, 리스너 객체를 생성하는 방법은 또 여러가지가 있다. 크게 Activity 자체가 implements를 이용하여 리스너인터페이스를 구현하는 방법과 View가 리스너를 구현하는 방식, 그리고 위 처럼 익명클래스를 사용하여 구현하는 방법이있다. 익명클래스를 사용하는 경우가 위와 같이 단 하나의 버튼에 대한 이벤트처리를 위한 리스너 이기 때문에 일회성으로 사용할 때 주로 사용한다.

PS. 이벤트 핸들러에도 우선순위가있다.
 - 이벤트를 처리하는 방식에 크게 2가지로 콜백메서드를 사용하는 방법과 리스너를 사용하는 방법이 있다고 하였다. 그렇다면 이 두가지를 모두 사용한다면 어떤 이벤트가 더 높은 우선순위를 갖게 될까? 정답은 리스너 이다. 더 자세히 나눠보면
 1. View의 리스너
 2. View의 콜백 메서드
 3. Activity의 콜백 메서드
순서로 우선순위를 갖게된다. 물론 이벤트 핸들러 자체가 이벤트 처리 수행과정이 종료되면 true를 리턴해 종료가 되기 때문에 이벤트가 3번 다 일어나는 것은 아니고 한번만 실행 되고 종료가 된다. 하지만 시스템적으로 이러한 우선순위가 있다는 것을 알아두면 도움이 될 날이 있을 것 같다.
 안드로이드 프로그래밍은 크게 Code와 Resource로 구성되어있다. 여기서 Code란 일반 프로그래밍 코드와 같은 의미로 특별할 게 없지만 Resource라는 개념은 진지하게 짚어두고 넘어 갈 필요가 있을 것 같다.
 

 기본적으로 이클립스에서 안드로이드 프로젝트를 생성하면 왼쪽과 같은 구조를 갖게되는데 이 중에서 res 폴더가 바로 Resource의 약자로 리소스파일들이 저장 될 공간이다. 그럼 이 리소스 파일들은 대체 무엇일까. 바로 프로그램의 논리적인 부분 외적인 것, 즉 외형을 이루는 이미지 파일이나 문자열, 음악파일이나 동영상 등이 되겠다. 

 웹표준에 대한 개념이 있는 사람이라면 html코드와 css를 분리 하여 관리하는 것과도 비슷한 개념이라고 생각할 수 있을 것 같다. 즉, 디자이너와 프로그래머의 역할 분담과 관리가 편해 지는 것이다.
  
 이곳을 구성하는 모든 파일들은 컴파일 시에 프로그램 코드와 함께 컴파일 되며 위에있는 assets 폴더 역시 프로그램에 필요한 자원들을 저장하는 폴더 이지만 컴파일러에게 부담을 줄 수 있는 큰 파일들을 컴파일하지 않고 원본 그대로 저장하여 사용 할 수 있게 해 준다. (멀티미디어 파일들을 저장할 때 주로 사용한다.)

자 그럼 res폴더 내부 폴더들을 하나씩 살펴보자!
 1. drawable : 이미지가 저장될 폴더로 현재 종류별로 3가지가있는데, 이는 에뮬레이터(단말기)의 해상도에따라 자동으로 이미지의 크기에 맞게 출력 할 수 있게 나누어 준 공간으로 일반적으로는 그냥 drawable 폴더를 새로 만들어 하나만 사용하거나 drawable-hdpi폴더를 사용한다. (현재 출시되는 스마트폰의 대부분이 고해상도를 지원하기 때문이다.)

 2. layout : 프로그램의 화면(Activity) 구성을 정의 해 놓은 폴더이다. 각종 레이아웃과 뷰 들의 배치나 속성들이 정의된다.
 3. values : 프로그램에서 사용 될 문자열, 배열, 색상, 크기, 스타일 등의 값들을 정의하는 곳이다.

- 위 캡쳐에서는 나오지 않았지만 이 외에도 주로 사용하는 폴더들이 있으니 알아보자.
 4. menu : 메뉴 구성파일이 저장된다. (에뮬레이터의 메뉴버튼 정의)
 5. raw : 기타 2진 파일을 저장하는 장소로 보통 용량이 작은 멀티미디어 파일을 저장한다.
 6. anim : 애니메이션을 정의한다. (화면의 움직임)
 7. xml : 프로그램에서 사용할 임의의 xml문서를 정의.

 위의 리소스 들을 사용하기위해서는 고유의 ID값을 가져야 하는데, 이 ID값을 관리하는곳이 바로 그 유명한 R,java라는 녀석이다. 이녀석은 매우 민감하기 때문에 함부러 건드려서도 안되고 또 그렇다고 너무 신경을안쓰면 안된다. (안드로이드를 처음 시작하면서 이녀석 때문에 컴파일이 안된적이 한두번이 아니었다. 안될때는 눈 딱 감고 R.java를 지우고 저장을하면 자체적으로 R.java가 초기화 되고 컴파일이 이상없이 잘 되기도 한다.) 

 위의 코드가 바로 가장 기본적으로 R.java가 가지고있는 ID 들이다. 모두 정수 형태로 저장되는 것을 확인 할 수 있다.


PS. 간혹 레이아웃 구성을 할 때 다른 xml 파일 또는 다른 Activity에 사용될 컴포넌트(예를 들어 버튼)라고해서 같은 아이디를 줘도 상관이 없을 거라고 생각할 수도 있는데 모든 ID는 R.java라는 하나의 java파일에서 관리 하기 때문에 절대 중복되어서는 안된다. (이를 최대한 방지하기위해 자동으로 생성되는 ID 값은 상황에 맞게 수정을 하도록 하자)

예제를 수행하다 오늘 갑자기 아래와 같은 에러 메세지가 뜨면서 apk파일이 인스톨 되지 않았다.


왠지 메모리(용량)과 관련된 에러 메세지 같다. logcat에서 더 자세한 사항을 확인하라는데 뭐 특별히 확인 할 수 있는 메세지가 있는 것도 아니다. 그래서 열심히 이곳저곳 정보를 찾아 헤매다 다음의 방법으로 해결을 할 수 있었다.

1. 에뮬레이터에 어플들이 너무 많다. 
 - 위의 경우 그냥 사용하지 않는 어플들을 몇개 삭제 해 주자. 
 - 아마도 안드로이드 예제들이 너무 많이 쌓여서 이런 문제가 생겼지 않았나 싶다. 

2. 에뮬레이터 내장 메모리 용량을 크게 잡아주자.
 - 이 해결방법이 가장 적절 할 것같다. 아무래도 현재 있는 어플들을 지우지안고도 해결이 가능하기 때문에..

 1) 콘솔에서 명령어로 실행 하는 방법.

 -emulator -partition-size 사이즈 @에뮬레이터명


 2) 이클립스에서 에뮬레이터 설정.


 콘솔과 명령어는 같다. 


ps. 또다른 방법으로 에뮬레이터 내의 log파일을 초기화 해주는 방법이 있다고 하는데, 버전마다 log파일 관리체계가 다른지현재 내가 쓰고있는전(2.2)에서는 log파일을 확인 할 수 없었다.




 

+ Recent posts