1. " 소스파일 " 과 " 리소스파일 " 에대하여 소스파일은우리가흔히알고있듯이프로그래밍언어를사용해서자신이만들고자하는프로그램을구현한파일입니다. 예전에작성된프로그램들은소스파일만으로이루어진프로그램도많았습니다. 하지만, 프로그램환경이점점더복잡해지고사용자인터페이스가다양해지면서인터페이스구성을서술식으로나열해서소스파일에표현하는것은한계가왔고작업효율을떨어트리게되어해결책이필요하게되었습니다. 사용자인터페이스를그림그리듯이구성할수있고이렇게구성된것을동일한형태로사용할수방법에대해연구한결과로탄생한것이리소스라는개념입니다. 우리가알고있는아이콘이나비트맵과같은것만이리소스가아니라사용자인터페이스를어떻게조합하고어떻게배치하는가에대한정보도모두리소스에포함되는개념입니다. 결국, 리소스라는개념은프로그램에서실행부와사용자인터페이스를분리할수있는개념을제공하여인터페이스를효율적으로설계하고유지보수할수있도록도와줍니다. 따라서대부분의프로그램들이리소스라는개념을가지고있습니다. 안드로이드프로젝트또한소스파일들과리소스파일들로구성되어있습니다. 여러분들이알고있듯이안드로이드프로그래밍은자바언어를사용하기때문에소스파일들은.java 로이루어져있습니다. 그런데하나특이한점은다른언어들이리소스파일을독자적인형식으로관리하는반면안드로이드프로젝트는리소스를 XML 형식으로사용하고있습니다. XML(extensible markup language) 은사용자정의태그를통해데이터를구조화하여저장하고, 이기종응용프로그램간에도구조화된데이터를교환하고, 사용할수있도록 ISO 에서제안한마크업언어입니다. XML 이사용자정의태그를사용하기때문에데이터구조의확장성이용이해지므로꾸준히업데이트될안드로이드플랫폼의응용프로그램개발에적합했을것입니다. 안드로이드플랫폼에컨트롤들이추가되더라도언어나파일의형식에는지장을주지않고, 사용자정의태그만추가하면사용가능하기때문입니다. 또한 XML 이이미널리알려진언어이기때문에자바언어와더불어사람들이보다쉽게접근할수있고, 안드로이드용응용프로그램을개발하기위해서언어를익히는데소비하는시간을따로필요로하지않아도될것입니다. 리소스가 XML 형식으로되어있다고해서 XML 을당장공부할필요는없습니다. 처음배울때에는매우단순한형식만사용하기때문에기본적인사용법만이해하면됩니다. 하지만나중에여러가지이유로 XML 이많이필요하기때문에 XML 에대해서는시간날때따로공부해두는것이좋습니다. 2. 기본프로젝트살펴보기 새로운프로젝트를생성하면해당프로젝트의폴더내에는여러개의폴더와파일이생성됩니다. 앞에서이야기했듯이이파일들은소스파일과리소스파일로나누어생각할수있으며소스파일은확장자가.java 이고, 리소스파일은확장자가.xml 로되어있는파일들입니다. 안드로이드프로젝트는기본소스파일, 배치와구성에관련된리소스파일, 프로그램에서사용할문자열에관련된리소스파일로구성되어있습니다. 예를들어 TipssoftApp 라는프로젝트를만들었다면아래와같이 3 가지파일이프로그래밍하는데일반적으로필요한파일들입니다. ( 나머지파일들은강좌를진행하면서필요할때마다추가적으로설명하도록하겠습니다. )
TipssoftAppActivity.java // 기본소스파일 main.xml // 배치와구성에관련된리소스파일 string.xml // 프로그램에서사용할문자열에관련된리소스파일 컴파일을하고나면 r.java 라는소스파일이하나추가되는데이파일은리소스파일을소스파일에서이용할수있도록연결해주는파일이고, 매번갱신되는파일이기때문에사용자가직접편집할필요가없습니다. 이제이파일들에대해서하나씩구체적으로설명드리겠습니다. 2.1 기본소스파일 이파일에는응용프로그램이어떠한흐름과방향으로수행될것인지, 응용프로그램이보여지는컨트롤중에서어떤컨트롤의어떤행위에관심을기울일것인지, 행위가발생했을때에는어떻게처리를할것인지등응용프로그램의실행에관한부분을구성해주어야합니다. 프로젝트폴더내에서기본소스파일은다음과같은경로에존재합니다. 프로젝트루트폴더 \src\( 패키지경로 )\ 프로젝트명 Activity.java 위의경로에서나타내는 ( 패키지경로 ) 는프로젝트생성시명시했던패키지경로말하며만약 com.example.tipssoft 라는패키지명을사용했고, 프로젝트명이 TipssoftApp 였다면경로는아래와같이구성되어있을것입니다. TipssoftAppProject\src\com\example\tipssoft\TipssoftAppActivity.java 기본소스파일을열어서내용을살펴보면다음과같은코드가구성되어있습니다. package com.example.tipssoft; import android.app.activity; import android.os.bundle; public class TipssoftAppActivity extends Activity @Override public void oncreate(bundle savedinstancestate) super.oncreate(savedinstancestate); setcontentview(r.layout.main); 안드로이드시스템은다른시스템과달리하나의응용프로그램이여러개의실행시점을가질수있도록설계되어있고, 이러한실행시점을액티비티 (Activity) 라고하며이러한개념을클래스화시켜놓은것이 Activity 클래스입니다. 위의코드에서볼수있듯이 TipssoftAppActivity 클래스는 Activity 클래스에서상속된클래스로구성되어있기때문에이프로그램의실질적인실행부라고보시면됩니다. 기본 Activity 클래스를그대로사용하면자신이구성한인터페이스를사용할수없기때문에 Activity 클래스의 oncreate 메소드를재정의하여이프로젝트에서구성한리소스파일을 setcontentview 함수로호출하여사용하면됩니다.
2.2 배치와구성에관련된리소스파일 이파일에는응용프로그램에보여지는컨트롤들 ( 버튼, 에디트, 리스트뷰등 ) 을어떻게생성하고, 배치하고, 레이아웃할것인지등을구성해주어야합니다. 안드로이드용응용프로그램은소스파일에직접코드를작성하여컨트롤들을생성할수도있지만 XML 로좀더쉽고, 편하고, 가볍게컨트롤들을구성할수있습니다. 기본적인프로젝트폴더에는아래와같은경로내에컨트롤리소스파일이존재합니다. 프로젝트루트폴더 \res\layout\main.xml 기본 XML 파일을열어서내용을살펴보면다음과같은코드가구성되어있습니다. <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="hello Tipssoft" /> </LinearLayout> 이파일의내용을살펴보면아래와같습니다. - <?xml version="1.0" encoding="utf-8"?> 이문서는 xml 버전 1.0 형식으로구성되어있으며문자포맷은 UTF-8 로구성되어있다는의미입니다. - LinearLayout XML 문법상으로 <LinearLayout... /> 는 LinearLayout 라는이름으로명명된하나의요소를의미합니다. LinearLayout 다음에나오는속성을참조하여레이아웃을구성하게합니다. 레이아웃에대한내용은추후에자세하게다루도록하겠습니다. - xmlns:android="url" 특정한그룹에서정해놓은 XML 태그정보를명시한 URL 에서얻어온후 android 라는네임스페이스로선언한것입니다. 1 에서설명한것처럼 XML 은태그를사용자정의로구성할수있는데이태그를사용자들에게마음대로정의해서사용하라고하면사용자가정의한리소스파일은안드로이드툴이해석할수없기때문에미리정의해둔태그정보들을가져와서사용하는것입니다. 당연한얘기겠지만네임스페이스의선언에해당하는 xmlns: 네임스페이스명 ="URL" 문장은해당네임스페이스태그들을사용하는문단의가장선두태그에반드시선언해주어야하고, 여러네임스페이스를사용하는경우하나의태그에서동시에여러개를선언할수도있습니다.
태그에네임스페이스를명시하여사용하면해당태그명이네임스페이스안에존재하는것인지컴파일시확인을할수있으며, 여러개의네임스페이스가존재하여태그명이충돌할경우에도해당태그가어떤네임스페이스에속하는태그인지정확하게알수있기때문에에러를방지할수도있습니다. 네임스페이스를사용할때에는다음과같은형식을사용합니다. 네임스페이스 : 요소태그명 ( 혹은속성태그명 ) - android:id="@+id/textview" XML 문법상으로 android 라는네임스페이스안의 id 속성에값을설정한것입니다. 기본프로젝트를생성했을때구성되는리소스파일에는 android:id 코드가존재하지않지만텍스트뷰를클릭하거나드래그하는등의컨트롤에발생하는액션에대한처리를소스파일에서하기위해서는 id 를사용해야합니다. id 나문자열을설정할때에는 " 기호를이용하는데 " 기호사이에있는값은명시된그대로사용되기도하고, @ 기호를문자열의선두에붙여서일련의해석과정을거친후에사용하기도합니다. id 에사용하는값의경우해당값은추가될리소스이거나이미추가된리소스를사용하는것이므로반드시 @ 기호를사용하여아래와같은문법에맞추어입력해주어야합니다. @[+][ 네임스페이스명 :]id/ 아이디명 [] 는생략가능한키워드이며 / 기호까지알맞은키워드를입력한후에는사용할 id 명을입력합니다. id 를추가하는경우에는 + 기호를명시해야하며만약이미존재하는 id 값을사용하는경우에는 @id 라고만명시할수있습니다. 경우에따라서는이 id 라는값도 android 네임스페이스에존재하는태그명이므로 @android:id 처럼네임스페이스를포함하여명시하여야합니다. - android:layout_width, android:layout_height XML 문법상으로는 android 라는네임스페이스안의 layout_width 와 layout_height 속성을설정한것입니다. 해당컨트롤의너비와높이를설정하는것으로사용할수있는키워드는아래와같습니다. fill_parent : 부모스크린의크기만큼컨트롤의너비나높이를설정한다. ( 예전에는 fill_parent 를사용했지만직관성을위하여 API8 부터는 match_parent 가추가되어두값을혼용한다. 두값은모두 -1 로정의되어있다. ) wrap_content : 설정한문자열의크기에맞도록컨트롤의너비나높이를설정한다. - android:text=" 문자열 " XML 문법상으로는 android 라는네임스페이스안의 text 속성을설정한것입니다. text 속성에문자열을설정하면해당문자열이컨트롤에출력됩니다. 출력되는문자열을직접입력해도되지만리소스에문자열을등록하여사용할수도있습니다. 2.3 프로그램에서사용할문자열에관련된리소스파일 이파일은응용프로그램에서출력되는문자열을하나의파일에구성하여, 필요시이파일만을
편집하여응용프로그램내의모든문자열을관리할목적으로사용됩니다. 응용프로그램을만들면서사용되는문자열은직접입력으로도출력이가능하지만이로인해문자열이리소스파일이나소스파일내에여기저기흩어지게되면문자열변경시에해당문자열을일괄적으로변경할수없기때문에작업이비효율적으로이루어집니다. 예를들어, 스마트폰에서실행되는응용프로그램은간단해도유명해지면다양한언어로번역되어배포될수있습니다. 이런경우문자열을직접입력하여프로그래밍했다면문자열을변경하기위해서소스전체를살펴봐야하는불편함이언어를바꿀때마다생길것입니다. 하지만문자열리소스파일을활용했다면해당파일만번역가에게맡겨각언어별로쉽고, 간단하게변경할수있을것입니다. 그래서문자열은이문자열리소스파일에구성하도록권장하고있으며이파일은아래와같은경로에있습니다. 프로젝트루트폴더 \res\values\strings.xml 기본소스파일을열어서내용을살펴보면다음과같은코드가구성되어있습니다. <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">tipssoftappactivity</string> </resources> 위의코드에서등록된문자열 "TipssoftAppActivity" 은컴파일시리소스에등록되며사용시에는소스파일나리소스파일에서리소스의 name 인 "app_name" 으로대신사용됩니다. 문자열리소스를사용하는방법은다음과같습니다. // android:text="tipssoftappactivity" 와동일한결과를가져온다. android:text="@string/app_name" - @ : 리소스 id 를명시할때와마찬가지로이항목은리소스를사용한다는것을의미한다. - string : 스트링리소스를의미한다. - / : 리소스의종류와리소스의 id 나 name 과같은값을분리하는역할을한다. - app_name : 스트링리소스중에서 hello 라는 name 을가진리소스의문자열값을사용하겠다는의미이다. 3. R 클래스에대하여 R 클래스는리소스를소스파일에서이용할수있도록연결해주는역할을합니다. 프로젝트가컴파일될때리소스로추가될데이터가있으면안드로이드툴이 R 클래스를구성하여 r.java 파일을생성하며아래의그림처럼소스코드에서 R 클래스를통하여리소스에접근할수있도록해줍니다.
위의그림을보면리소스파일에텍스트뷰하나와버튼두개가구성되어있습니다. 리소스코드에서컨트롤에부여한 ID 는해당리소스파일이컴파일될때리소스클래스인 R 클래스내부의 ID 클래스에등록되며, 소스코드에서는 R.id.ID 명 (R 클래스내부의 id 클래스내부에 public static final int 로선언된 ID 명 ) 을 findviewbyid 메소드의인자로넘겨호출하여리소스파일에서구성한컨트롤중에서 ID 와대응하는컨트롤을사용할수있습니다. R 클래스파일은프로젝트를컴파일할때에만재생성되기때문에한번도컴파일하지않은프로젝트의경우파일은존재하지않을수있으며존재하는파일은사용자가변경해서는안됩니다. 만약컴파일을통하여파일이생성된경우해당파일의경로는다음과같으며 ( 패키지경로 ) 의의미는 2.1 에서설명한부분과동일합니다. 프로젝트루트폴더 \gen\( 패키지경로 )\R.java 기본리소스클래스파일을열어서내용을살펴보면다음과같은코드가구성되어있습니다. package com.example.tipssoft; public final class R public static final class attr public static final class drawable public static final int icon=0x7f020000; public static final class layout public static final int main=0x7f030000;
public static final class string public static final int app_name=0x7f040000; 위의코드에서 R 클래스내부의 layout 클래스에선언된 main 변수는 XML 컨트롤리소스파일인 main.xml 을의미하며 string 클래스의 app_name 변수는 2.3 에설명한문자열리소스파일에등록된문자열의 name 을의미합니다. 4. 응용프로그램에 Hello Tipssoft 출력하기 응용프로그램에서텍스트를출력하기위해서는텍스트뷰를사용해야하고, 텍스트뷰를사용하는방법은두가지가있습니다. 4.1 리소스파일을이용하는방법 기본프로젝트를생성했을때기본으로구성되는리소스파일과소스파일이이방법에해당하며리소스파일에구성된컨트롤들을소스파일에서불러와서사용하며기본소스코드는다음과같습니다. package com.example.firstexam; import android.app.activity; import android.os.bundle; public class FirstExamActivity extends Activity @Override public void oncreate(bundle savedinstancestate) super.oncreate(savedinstancestate); setcontentview(r.layout.main); 위의코드에서 settcontentview 함수는응용프로그램에보여질컨트롤을설정할때호출하는함수입니다. R.layout.main 은리소스를구성한 XML 파일명 main.xml 을말하며해당리소스값은 R 클래스내부의 layout 클래스에 public static final int main 으로선언되어있습니다. 4.2 소스코드로컨트롤을생성하는방법 리소스파일에서리소스를구성하지않고자바소스코드내부에서직접컨트롤을생성해서응용프로그램에배치하고자할때사용하는방법이며다음과같이코드를구성할수있습니다. package com.example.firstexam; import android.app.activity; import android.os.bundle; import android.widget.textview; public class FirstExamActivity extends Activity
@Override public void oncreate(bundle savedinstancestate) super.oncreate(savedinstancestate); // 텍스트뷰생성 TextView tv = new TextView(this); // 텍스트뷰에문자열설정 tv.settext("hello, Tipssoft"); // 텍스트뷰를어플리케이션에보이도록설정한다. setcontentview(tv); 위의코드는어떠한리소스도사용하지않고, 오로지소스코드를이용하여컨트롤을생성하고, 배치한것입니다. 이렇게컨트롤이하나만존재하는코드는간단하게자바코드로도구성할수있지만중첩된레이아웃과컨트롤의배치가필요할시에는매우복잡해집니다.