이전 포스트에서 실행된 프로젝트가 어떻게 구성되어 있고 어떤 코드에 의해 보여지고 있는지 알아보겠습니다.
C와 Java만 학습하신 분들은 open 되어 있는 2개의 파일에서 먼저 'Hello world!"라는 글씨를 찾고 계실지도 모릅니다. 하지만 아무리 찾아봐도 화면에 보여지는 'Hello world!"라는 문구가 보이질 않으실 겁니다. 심지어 main() 메소드도 보이질 않아 당황했을지도 모릅니다. 사실 제가 처음 안드로이드를 접했을 때 했던 행동입니다.
우선 알아둘 것은 안드로이드는 C나 Java와 다르게 프로그램의 시작점인 main() Method가 없습니다.
"뭐야!? 그럼 어디서부터 시작이야?? 그냥 자바 소스파일이 하나니까 그것 부터 시작하나??" 그럴리가 없겠죠. 우선 이런 구조적인 흐름에 대한 생각은 접어두고 화면에 글씨가 보여지는 주요 코딩부분만 알아보겠습니다. 나머진 차차 설명드리겠습니다.
우선 아래 그림처럼 Package Explorer에 'Hello'라는 이름의 프로젝트가 보입니다. 안에 엄청 많은 폴더와 파일들이 보이죠. 심지어 자바로 안드로이드 프로그래밍을 한다면서 java파일만 있는 것도 아니고요. 답답해 집니다. 해결해 보죠.
프로젝트 구성파일에 대한 설명은 잠시 뒤에 하고 open되어 있는 파일 2개를 통해 화면에 보여지는 과정을 알아보겠습니다.
지속적으로 언급했듯이 안드로이드 어플은 Java언어로 개발합니다. 당연히 java 소스파일의 코드 내용으로 동작하게 되어있죠. 저는 보통 프로그램을 처음 공부하는 친구들에게 이렇게 코드를 이렇게 해석하도록 유도합니다.
"프로그램을 만든다는 것은 요리로 비유하면 레시피를 만드는 것이다. 즉, 본인이 어떤 음식을 완성하는 순서를 글로 써놓는 것이다. 프로그램을 실행시키는 컴퓨터는 단순한 요리사다. 이 요리사는 만드는 능력은 좋은데 창조는 못한다. 그리고 중요한 것. 한번에 두가지 작업을 하지 못한다. 그렇기 때문에 레시피는 요리를 만드는 순서대로 반드시 작성되어 있어야 한다. 심지어 냄비와 칼을 준비해야 한다는 것도 써놓아야 한다. 냄비에 물을 넣으라고 쓰고 다음줄에 냄비를 준비하라 라고 쓰면 안된다. 요리사(컴퓨터)는 무조건 순서대로 진행한다."
프로그램을 좀더 깊이있게 학습하면 위에 소개한 '단순한 요리사'가 아닌 멀티플레이어 요리사(?)를 만나게 되는데 그건 나중에 소개하고 우선 처음 코드를 접할때는 위의 방법으로 설명합니다. 여기도 마찬가지 입니다. 아직 설명 못한 부분이 많지만 우선 보이는 java 소스파일은 하나이니 어떻게 시작되는 건지는 모르겠지만 이 소스파일이 실행된다는 것은 유추할 수 있겠죠.
Open되어 있는 'MainActivity.java'를 보겠습니다.
package com.andsoft.hello;
import android.os.Bundle; import android.app.Activity; import android.view.Menu;
public class MainActivity extends Activity {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }
@Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; }
} |
알수없는 코드들로 보이실지 모르겠지만 새로운 명령어를 배우는게 아닙니다. 위 코드는 java언어로 작성된 것입니다. 당연히 Java언어의 문법 규칙을 따르고 있습니다. 가끔 강의를 하다보면 Java를 학습한 친구가 안드로이의 문법을 모르겠다고 말하는 경우가 있습니다. 물론 구조나 원리는 아직 배워야 하지만 실제 어플의 동작을 결정하는 코드의 작성은 자바와 문법적 차이가 없습니다. 아니 그냥 자바 문법입니다. 자바를 어느정도 아시는 분이 지금 이 코드를 보고 해석을 못하는 것은 문법을 몰라서가 아니라 사용되어지고 있는 클래스들과 메소드들을 몰라서 입니다. 즉, 레고 블럭을 만들때 네모모양이나 세모 모양의 블럭만 가지고 만들어 봤는데 동그란 모양의 블럭이 내 앞에 있는 겁니다. 어떻게 쓰는지 모르겠죠. 하지만 한두번만 사용된 예를 보여주면 어렵지 않게 여러곳에 사용할 수 있습니다. 중요한 건 레고 블럭은 아무리 다양한 모양이 있어도 조립하는 방식은 같다는 것이죠. 그래서 남녀노소 누구나 기본적인 블럭 조립방법만 익히면 새로운 모양의 블럭을 만나도 용도만 알면 조립할 수 있다는 것이죠. 자바가 대표적으로 이런 구조로 되어있죠(정확히는 OOP). 위 코드를 보면 클래스나 메소드의 이름들은 생소하지만 코딩 방식은 자바로 개발할 때와 같다는 것이죠.
세부적인 것은 차후에 설명드리고 우선 MainActivity라는 이름의 클래스가 선언되어 있다는 것을 알 수있습니다. 일단 코드 전체에 클래스가 이거 하나 선언되어 있으니까 이 클래스가 객체로 만들어 져서 화면에 글씨를 출력한다는 것을 유출할 수 있습니다.
public class MainActivity extends Activity{ .... } |
클래스의 선언부에 extends가 들어간 걸로 봐서 Activity라는 클래스를 상속해서 클래스를 만들고 있다는 것을 알수 있습니다. 나중에 설명드리겠지만 바로 이 상속받은 'Activity' 클래스가 화면출력을 담당하고 있는 클래스 입니다. 이 클래스를 상속 받음으로서 화면에 무엇인가를 보여주기 위한 수 많은 준비 코드를 생략할 수 있는 것이죠. 우리는 어떤 방법으로 화면에 보여지는 가는 고민할 필요없이 그냥 무엇을 보여줄까만 고민하면 되도록 만들어 놓은 클래스입니다. 자세한 설명은 다음에 다시 하도록 하겠습니다.
@Override protected void onCreate(Bundle savedInstanceState) { ...... }
@Override public boolean onCreateOptionsMenu(Menu menu) { ....... } |
클래스 안에 두개의 메소드가 보이며 '@Override'가 보이는 걸 보면 이 두개의 메소드는 상속받아 온 Activity 클래스의 메소드라는 것을 알 수 있습니다. 메소드의 이름만으로도 대충 역할을 짐작할 수 있겠죠. onCreate() 메소드는 '만들어 질때' 라는 의미니까 이 메소드는 화면이 만들어질때 호출되는 메소드라는 것으로 유추해 봄직 합니다. 메소드명이 'on'으로 시작되는 메소드는 대부분 callback 메소드인 경우가 많습니다. callback 메소드는 일반 메소드와 다르게 여러분이 호출을 하는 것이 아니라 운영체제 즉, 안드로이드가 어떤 상황이 되었을때 호출하는 것을 말합니다. 자바 학습을 충실히 하셨다면 아시리라 생각됩니다. 안드로이드에서는 이 callback 메소드의 활용이 무엇보다 중요합니다. 앞으로 배우게 되겠지만 가물가물 한 분은 다시한번 시간을 들여 callback에 대한 정리해보시기 바랍니다.
결국 이 메소드가 어플이 실행되고 화면이 만들어지면 호출되니까 이 메소드 안에 보여질 내용물을 작성해 놓았겠구나. 라고 생각하실 수 있다면 센스 만점입니다. 정답입니다. 이 메소드 안에 보여질 내용물을 결정하여 MainActivity 클래스에게 설정해 주면 됩니다.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 부모클래스의 메소드를 호출하는 것이니까 우선 패스 setContentView(R.layout.activity_main); // 보여질 내용물(뷰)을 설정 } |
이 메소드의 매개변수는 나중에 다시 하겠습니다. 저 객체의 역할은 갑작스럽게 화면이 종료되었을 때 이전 상태를 저장하고 있는 녀석이다 정도로만 이해하시고 넘어가겠습니다. 여러분이 엑셀에서 어떤 작업을 하다가 갑자기 다운되었을 때 다시 실행시키면 마지막 상태가 자동으로 저장되어 보여지는 경우가 있죠. 그런 역할을 저 매개변수가 한다 정도로 이해하기시 바랍니다. 결국 이 메소드안에서 super를 이용하여 부모클래스의 메소드에게 매개변수를 전달하는 부분을 제외하면 딱 하나의 메소드 호출문만 있는 겁니다.
코드를 보면 'setContentView()'라는 메소드를 호출하고 있고 매개변수로 'R.layout.activity_main'을 전달하고 있다는 것을 알 수 있습니다. 중요한건 저 'setContentView()'라는 메소드를 우리는 만든 적이 없다는 것이죠. 그렇다는 것은 이 메소드가 부모 클래스의 메소드라는 것이고 자식 클래스는 부모클래스의 멤버를 마음대로 사용할 수 있으니 'setContentView()'를 만들지 않고 사용하고 있다는 것을 확인할 수 있습니다. 이 'setContentView()'메소드가 어떤 역할을 하는지 배운적은 없지만 이름만으로도 유추가 어느정도 가능하리라 봅니다. 대부분의 API들에서 제공하고 있는 클래스들은 변수명이나 메소드명 만으로 그 의미나 역할을 짐작할 수 있도록 명명하고 있습니다. 그럼 유추해 보죠. 먼저 'set'으로 시작하고 있으니 뭔가를 설정한다는 것이고 'Content'라는 단어는 내용물이고 'View'는 보이는 것 또는 보여지는 것이니까. 종합해 보면 액티비티가 화면 출력을 담당하고 있는 클래스이니까 이 클래스에게 명령을 내리고 있는 것이네요. "화면에 보여지는 내용물을 설정하겠다. 그 내용물은 매개변수로 전달하겠다." 라고 해석할 수 있을 것 같습니다. 안드로이드에서 화면에 무엇인가를 보여줄 때 반드시 알고 있어야 하는 클래스가 Activity와 View입니다. 나중에 다시 설명하겠지만 안드로이드에서 View라는 용어는 화면에 보여지는 어떤 것(이미지,텍스트,버튼 등)을 지칭합니다. 우리가 인테리어를 할 때 벽에 액자를 걸거나 벽장을 설치 했다고 했을 때 벽을 액티비티 즉, 화면이라고 보면 장식되어 있는 액자나 벽장 또는 화분 같은 것들을 뷰라고 합니다. 다음 강좌에서 다시 보기로 하고 일단 이 메소드가 결과적으로 화면에 글씨를 보여주게 하는 결정적인 메소드라는 것을 알 수 있습니다. 가장 중요하고 기본적인 메소드라고 할 수 있겠죠. 전체적으로 종합해보면 프로젝트가 실행되면 당연히 화면에 무엇이든 보여야 하니까 화면출력을 담당하는 액티비티 클래스의 객체가 만들어 질 것이고 이 객체가 화면을 만들 때 'onCreate()'라는 메소드가 호출되며 이 메소드 안에서 'setContentView()'메소드를 호출 함으로서 화면에 보여질 내용물이 정해진다는 흐름을 해석할 수 있었습니다.
그럼 화면에 보여지는 내용물은 무엇일까요?
'setContentView()'메소드의 매개변수를 전달한 'R.layout.activity_main'이라는 코드가 무엇인가? 이에 대한 설명은 다음에 하고 뭔지는 모르겠지만 이름을 보니 어디서 본 적이 있는 것같습니다.
처음 프로젝트를 만들었을 때 자동으로 open되어 있던 파일이 2개 였던거 기억하시죠? 우린 그 중에 'MainActivity.java' 파일을 보고 있었죠. 이 파일 말고 옆에 열려있는 'activity_main.xml'파일이 보이시나요? 예전 버전에서는 이 파일만 open해줬었습니다.
아무튼 'setContentView()'메소드의 매개변수를 전달한 'R.layout.activity_main' 코드가 이 xml파일을 의미하고 있다고 유출할 수 있습니다. 단지 표시 방식이 파일이름과 확장자가 아니라서 이상해 보일 수 도 있는데요. 이건 나중에 다시 설명드리죠. 잘은 모르겠지만 화면에 보여질 내용물르 설정하라는 'setContentView()'메소드에게 이 파일을 전달했으니 화면에 'Hello world!'라는 글씨는 이 xml파일 안에 써져 있는 것 같습니다. 그럼 'activity_main.xml'을 보겠습니다. 파일을 선택하시면 아래 그림처럼 애뮬레이터의 화면에 보여졌던 모습과 같은 모양의 화면이 보여집니다.
"아! 결과적으로 이 xml파일에서 만든 화면이 어플이 실행 되었을때 보여지는 화면이구나." 라고 이해하시면 됩니다.
처음 프로젝트를 생성했을 때 이 2개의 파일을 open해 주는 것도 이 2개가 여러분들이 화면에 무엇인가를 보여줄 때 건드려야 하는 파일들이기 때문입니다. 우선은 우리가 생성한 프로젝트가 이런 코드들에 의해 실행 되고 있다는 정도만 설명 드렸습니다.
우리는 아직 프로젝트안에 있는 저 많은 파일들에 대해 알지 못하며 프로그램이 실행될 때 가장 중요한 시작점도 역시 알지 못하고 있습니다. 자바를 어느정도 알고 있으신 분들은 저 자바파일만 보면 더더욱 혼란스러울 수도 있습니다. 우리가 본 'MainActivity.java' 소스파일은 그 어디에도 MainActivity Class를 객체로 만들지 않고 있다는 것이죠. 클래스를 아무리 잘 만들어도 객체를 만들지 않으면 의미가 없죠.
자. 이제 본격적으로 안드로이드 프로젝트에 대해 알아봐야겠죠. 다음 포스트에서 뵙겠습니다.
'Android 어플개발 강좌' 카테고리의 다른 글
[게임제작으로 배우는 안드로이드 어플 개발]6. View와 Widget 1 (0) | 2015.03.27 |
---|---|
[게임제작으로 배우는 안드로이드 어플 개발]5. 안드로이드 프로젝트 구조 3 (0) | 2015.03.27 |
[게임제작으로 배우는 안드로이드 어플 개발]3. 안드로이드 프로젝트 구조 1 (0) | 2015.03.27 |
[게임제작으로 배우는 안드로이드 어플 개발]2. 안드로이드 프로젝트 만들기 (0) | 2015.03.27 |
[게임제작으로 배우는 안드로이드 어플 개발]1. 개발 도구 준비 (2) | 2015.03.27 |