하이브리드 앱 강좌 #2. 안드로이드 앱 개발의 기초

개요

이 글에서는 본격적인 하이브리드 앱 개발에 앞서 안드로이드 앱 개발에 필요한 기초 개념을 설명합니다.
프로젝트 생성, 앱 실행, 레이아웃, 이벤트 처리를 간략한 예제를 통해 다룹니다.

새 프로젝트 생성

이클립스를 처음으로 실행한 화면에서 자식창인 Android IDE 옆의 X 버튼을 클릭해서 닫고 나면 다음 화면을 볼 수 있습니다.

첫 화면

새 프로젝트1

툴바 첫번째에 있는 New 아이콘 옆의 아래 화살표(▼)를 클릭하고 Android Application Project를 클릭합니다.

새 프로젝트2

New Android Application 창에서 다음 항목을 지정해야 합니다.

  • Application Name: 구글 플레이스토어, 앱 목록 등에 나타나는 앱 이름을 지정합니다.
  • Project Name: 개발 중에 이클립스에 저장될 프로젝트명을 지정합니다.
  • Package Name: 개개의 어플을 구분하는 고유한 아이디에 해당합니다. 패키지명이 동일한 어플이 여러 개가 있더라도 한 폰에는 하나만 설치할 수 있습니다. 따라서 각 어플은 전 세계에서 중복되지 않는 패키지 이름을 가져야 하고, 관례적으로는 개발자의 웹사이트의 도메인 네임을 뒤집어서 많이 사용합니다.
  • Minimum Required SDK: 이 앱이 호환되는 안드로이드 운영체제 버전의 최솟값을 지정합니다. 현재 기준으로는 Android 2.3.3에 해당하는 API 10 버전을 권장합니다.
  • Target SDK: 이 앱이 사용할 모든 기능을 제공하는 안드로이드 운영체제 버전의 최솟값을 지정합니다. Minimum Required SDK에 비해 너무 높은 값을 지정할 경우 하위 버전 호환을 위한 코드 작성이 길어집니다. 개발의 편의성을 위해서는 Minimum Required SDK와 동일하게 설정하는 것을 권장합니다.
  • Compile With: 기본값대로 최신 컴파일러를 사용하면 됩니다.
  • Theme: 배경색, 글자색, 버튼색 등 어플의 전반적인 색상을 Dark, Light 등에서 선택할 수 있습니다. 안드로이드 설정 화면을 예를 들면 갤럭시 시리즈는 배경색이 검정인 Dark Theme, 옵티머스 시리즈는 배경색이 흰색인 Light Theme를 사용하고 있습니다.

Minimum Required SDK에 API 10을 권장하는 이유를 알기 위해서는 아래 링크를 통해 현재 전세계에서 사용중인 안드로이드 기기의 운영체제 버전에 대한 통계를 확인해야 합니다.

Dashboards | Android Developers

버전 통계

2013년 8월 1일 기준으로 전세계에서 안드로이드 2.3.3 진저브레드 (API 10) 이상의 버전을 사용중인 사람이 96.1%이므로 이를 기준으로 삼는 것이 좋습니다.
안드로이드 2.2 프로요 (API 8) 버전을 기준으로 삼을 경우 추가로 2.6%의 사람들에게 어플을 제공할 수 있지만 진저브레드 버전에서만 제공하는 기능들을 사용하기 까다로워집니다.

새 프로젝트3

다음 단계에서는 앱의 아이콘을 직접 만들지, 액티비티를 자동으로 생성할지, Workspace 폴더 내에 새 프로젝트를 생성할지 여부를 묻습니다.
기본값대로 두고 Next 버튼을 클릭합니다.

새 프로젝트4

앞에서 앱의 아이콘을 직접 만들겠다고 선택했기 때문에 나타나는 화면입니다.
직접 이미지를 선택하거나, 클립아트 중에서 고르거나, 원하는 문자열을 통해서 아이콘을 생성할 수 있습니다.

새 프로젝트5

액티비티를 자동으로 생성하겠다고 선택했기 때문에 나타나는 화면입니다.
Create Activity를 체크된 상태로 두고, 목록 중에서 Blank Activity를 선택합니다.

새 프로젝트6

생성할 액티비티에 관한 정보를 입력합니다.

  • Activity Name: 생성할 Java 클래스의 이름입니다. ?????Activity 와 같은 형태로 지정합니다.
  • Layout Name: 생성할 xml 파일의 이름입니다. layout_?????와 같은 형태로 지정합니다.
  • Navigation Type: 레이아웃 형태를 지정합니다. 일단은 None을 선택합니다.

새 프로젝트 생성됨

여기까지 마친 뒤에는 위와 같은 화면을 볼 수 있습니다.

안드로이드 프로젝트 구조

프로젝트 구조

  • src: .java 파일이 저장됩니다.
  • assets: 앱에 들어갈 .htm, .css, .png, .jpg, .mp4 등의 파일들을 종류 제한, 파일명 제한 없이 자유롭게 넣을 수 있습니다. 하위 폴더를 생성할 수 있습니다. 앱의 패키지 파일(.apk)의 압축을 풀면 그대로 노출됩니다. AssetManager를 통해 접근합니다.
  • res: 앱에 들어갈 이미지, 레이아웃, 메뉴, 문자열 등을 넣을 수 있습니다. 해당되는 폴더에 안에만 파일을 추가할 수 있고, 임의로 하위 폴더를 생성할 수 없습니다. 앱의 패키지 파일의 압축을 풀어도 노출되지 않습니다. R이라는 클래스를 통해 접근합니다.
  • AndroidManifest.xml: 앱에 관한 정보를 기록하는 파일로서, 어플명, SDK 버전, 액티비티 목록, 앱이 사용하는 권한(Permission) 등을 기록합니다. 이 파일에 기록되지 않은 액티비티를 실행하거나, 여기에 기록되지 않은 권한을 사용하려고 하면 앱의 실행이 중단됩니다.

앱 실행

실행1

앱을 처음으로 실행하기 위해서는 툴바에서 Run Project 버튼 옆의 아래 화살표(▼)를 클릭하고 Run Configurations를 클릭합니다.

실행2

좌측 화면에서 Android Application을 선택하고 New launch configuration 아이콘을 클릭합니다.

실행3

Project를 지정하기 위해 Browse 버튼을 클릭합니다.

실행4

Project Selection 창에서 실행하려는 프로젝트를 선택하고 OK 버튼을 클릭합니다.

실행5

Name 칸에 적당한 이름을 적습니다.
대개는 프로젝트명을 복사, 붙여넣기 하는 것을 권장합니다.
다음으로는 Apply 버튼을 클릭하고 Run 버튼을 눌러서 실행합니다.

실행6

앱을 처음 실행할 때에만 앞의 과정이 필요합니다.
다음부터 앱을 실행할 때에는 Run Project 버튼 옆의 아래 화살표(▼)를 클릭하고 해당 프로젝트를 선택하면 됩니다.

실행7

PC와 케이블로 연결되어 있던 스마트폰에서 해당 앱이 실행됩니다.

실행8

앱을 종료해 보면 설치된 앱 목록에 방금 실행한 앱이 있는 것을 확인할 수 있습니다.

레이아웃

레이아웃01

새 프로젝트를 생성했을 때에 기본적으로 적용된 레이아웃은 Relative Layout입니다.
이번 예제에서는 이것을 Linear Layout으로 바꾸어 줍니다.
이클립스의 오른쪽 위에 있는 Outline 창에서 RelativeLayout을 선택하고 마우스 오른쪽 버튼을 클릭합니다.
컨텍스트 메뉴에서 Change Layout을 클릭합니다.

레이아웃02

Change Layout창에서 New Layout Type으로 LinearLayout(Vertical)을 선택하고 OK 버튼을 클릭합니다.

레이아웃03

다음으로는 Palette에서 버튼을 선택해서 레이아웃 창으로 드래그합니다.

레이아웃04

TextView 아래에 Button이 배치된 것을 볼 수 있습니다.
버튼의 width를 조절하기 위해서 버튼이 선택된 상태에서 오른쪽 아래의 Properties 창의 Width를 선택합니다.
Width 필드가 보이지 않을 경우 Layout Parameters 필드 왼쪽에 있는 [+]버튼을 클릭하면 됩니다.

레이아웃05

기본값으로 지정되어 있던 wrap_content 대신에 match_parent를 선택합니다.

레이아웃06

버튼의 width가 늘어나 화면을 가득 채우는 것을 볼 수 있습니다.
다음으로는 버튼의 텍스트를 수정하기 위해 오른쪽 위의 Outline 창에서 버튼을 선택하고 마우스 오른쪽 버튼을 클릭합니다.
컨텍스트 메뉴에서 Edit Text를 클릭합니다.

레이아웃07

Resource Chooser 창에서 New String 버튼을 눌러 새로운 String을 생성합니다.

레이아웃08

Create New Android String 창에서 String 칸에 원하는 문자열을 입력합니다.
New R.string. 칸에는 이 문자열을 할당할 java 변수명을 입력합니다.
이렇게 하면 .java 파일에서 R.string.(변수명)으로 해당 String 값을 사용할 수 있게 됩니다.
입력이 완료되면 OK 버튼을 클릭합니다.

레이아웃09

다시 Resource Chooser 창에서 조금 전에 생성한 Android String을 확인할 수 있습니다.
OK 버튼을 클릭합니다.

레이아웃10

버튼의 텍스트가 바뀐 것을 확인할 수 있습니다.

레이아웃11

이번에는 TextView의 weight를 조절해서 버튼의 높이는 최소가 되고, TextView의 높이는 최대가 되도록 조절하겠습니다.
화면에서 TextView를 클릭하여 선택합니다.
오른쪽 아래의 Properties 창에서 Weight 필드를 선택하고 숫자 1을 입력하고 엔터키를 눌러 입력합니다.

레이아웃12

TextView의 높이가 늘어나 최대값이 되고 Button은 최소한의 높이만을 가진 채로 화면 아래에 배치되는 것을 확인할 수 있습니다.

이벤트 처리 #1: id 지정

이벤트를 처리하기 위해서는 id가 필요합니다.
앞에서 생성한 Button과 TextView에 각각 id를 지정하겠습니다.

이벤트01

Outline 창에서 버튼을 선택하고 마우스 오른쪽 버튼을 클릭한 뒤 컨텍스트 메뉴에서 Edit ID를 선택합니다.

이벤트02

Rename Resource 창에서 New Name에 원하는 id를 입력합니다.
이 예제에서는 buttonTest로 지정합니다.

이벤트03

마찬가지로 텍스트뷰를 선택하고 마우스 오른쪽 버튼을 클릭한 뒤 컨텍스트 메뉴에서 Assign ID를 선택합니다.

이벤트04

텍스트뷰의 id를 textViewTest로 지정합니다.
버튼과 텍스트뷰의 id 지정이 끝난 뒤에 Outline을 보면 다음과 같습니다.

이벤트05

이벤트 처리 #2: 멤버변수 선언

이벤트06

화면 왼쪽 위의 Package Explorer 창에서 MainActivity.java를 더블클릭하면 아래와 같은 코드를 볼 수 있습니다.

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;
	}

}

MainActivity 클래스 안에 멤버변수로 textViewTest, buttonTest를 선언합니다.
또한 ButtonTest의 클릭 이벤트를 처리할 OnClickListener를 선언합니다.

public class MainActivity extends Activity {

	TextView textViewTest;
	Button buttonTest;
	OnClickListener cListener;

	@Override
	protected void onCreate(Bundle savedInstanceState) { ... }

	@Override
	public boolean onCreateOptionsMenu(Menu menu) { ... }

}

이 때에 보다 쉽게 입력하기 위해서는 이클립스의 자동완성 기능을 사용하는 것이 편리합니다.
예를 들어 OnClickListener를 전부 입력할 필요 없이 onclickl까지 입력한 상태에서 Ctrl+Space bar를 입력하면 자동완성이 가능한 단어들의 목록을 볼 수 있습니다.

이벤트07

여기에서는 android.view.View에 포함된 OnClickListener를 선택하면 됩니다.

한편 TextView와 Button에 빨간색 밑줄이 그어진 것은 해당 클래스가 import 되어 있지 않기 때문입니다.
이를 해결하기 위해서는 TextView에 마우스 포인터를 가져다 두고 잠시 기다리면 됩니다.

이벤트08

이러한 팝업창에서 import ‘TextView’ (android.widget)을 선택하면 됩니다.

이벤트 처리 #3. 멤버변수 연결

앞에서 선언한 TextView, Button 변수를 실제 텍스트뷰, 버튼과 연결해야 합니다.
onCreate 메서드에서 findViewById() 메서드를 사용하면 됩니다.
주의할 점은 반드시 setContentView() 메서드가 실행된 이후에 findViewById() 메서드를 실행해야 한다는 점입니다.

public class MainActivity extends Activity {

	...

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		textViewTest = (TextView)findViewById(R.id.textViewTest);
		buttonTest = (Button)findViewById(R.id.buttonTest);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) { ... }

}

이벤트 처리 #4. 이벤트 리스너

이벤트 리스너는 어디에서 생성해도 상관 없으나 이번 예제에서는 다른 멤버변수와 마찬가지로 onCreate 메서드 안에서 생성하겠습니다.
OnClickListener는 onClick() 메서드를 구현해야 합니다.
cListener = new OnClickListener까지만 입력한 후에 이클립스의 자동완성 기능(Ctrl+Space bar)을 사용하면 필요한 코드를 작성해 줍니다.
onClick 메서드 안에서는 파라미터인 v를 통해서 어떤 버튼이 클릭된 것인지를 확인하고 그에 맞게 코드를 실행합니다.
마지막으로는 cListener를 button에 OnClickLister로 지정해 줍니다.

public class MainActivity extends Activity {
	
	TextView textViewTest;
	Button buttonTest;
	OnClickListener cListener;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		...
		
		cListener = new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				switch (v.getId()) {
				case R.id.buttonTest:
					textViewTest.setText("buttonTest가 클릭됨");
					break;
				default:
					break;
				}				
			}
		};

		buttonTest.setOnClickListener(cListener);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) { ... }

}

앱을 실행해 보면 다음과 같은 화면을 볼 수 있습니다.

이벤트09

버튼을 클릭하면 텍스트뷰에 새로운 문자열이 표시되는 것을 볼 수 있습니다.

이벤트10

이번 강좌에서는 안드로이드 앱 개발의 기초를 다루었습니다.
다음 강좌에서부터 본격적인 하이브리드 앱 개발을 다루겠습니다.

관련 포스트

“하이브리드 앱 강좌 #2. 안드로이드 앱 개발의 기초”에 대한 29개의 댓글

    1. 정말 감사합니다~ 책봐도 다 옛날버전으로 되어있어서 힘들었는데 감사합니다!!

  1. 이번강좌 이벤트처리 #4 에서 OnClickListener 자동완성이 강좌와 다르게 나옵니다

    public void onClick(DialogInterface dialog, int which)

    ㅠㅠ 왜 다른것일까요?

      1. 완전 초보인데요..
        import view 해야 한다는게
        import view.view; 를 선언해주어야 한다는건가요?
        View v 에러를 처리하면
        OnClickListener 에러가 생깁니다..
        도와주세요.

  2. 위에 질문 남겼던 사람입니다
    변수 선언할 때 OnClickListener 자동 완성할 때
    dialoginterface 포함된것을 잘못 눌러 나타나게 된것을 알게 되었습니다
    그다음에 andriod.view 포함된것 다시 수정할려고 하니

    변수 명이 자동으로
    android.view.View.OnClickListener
    이 되어버리네요
    그래서

    cListener = new android.view.View.OnClickListener() {
    public void onClick(View v) {
    // TODO Auto-generated method stub
    }
    };

    부분도 이렇게 바뀌게 되었는데

    android.view.View 없이 사용되도록 할 순 없나요?

    1. ;; 윗부분에 숨겨진 import 가 있었네요

      지우고 하니 해결 되었습니다

      강좌 잘보고 있습니다 감사합니다 ^^;;;

  3. 정말 잘보고 갑니다. 왠만한 다른 블로그들 보다 훨씬 잘 설명해주셔서
    많은 도움이 되었습니다.

  4. 좋은 강좌 감사합니다.^^
    한동안 컴퓨터를 안하다가 하니 초보적인 질문이 있습니다.

    buttonTest.setOnClickListener(cListener);
    이렇게 특정 아이디를 부여한 버튼을 클릭할시에 이벤트리스너를 달았는데요

    ‘onClick 메서드 안에서는 파라미터인 v를 통해서 어떤 버튼이 클릭된 것인지를 확인하고 그에 맞게 코드를 실행합니다’
    이부분에서 onClick 안에서의 스위치문으로 다시 아이디를 체크하는 이유가 무엇인지 궁금합니다.

    스위치 구문을 다 삭제하고 그냥 textViewTest.setText(“buttonTest가 클릭됨”);
    이렇게 하면 어떤 차이점이 있는지요.

    너무 오랜만에 컴퓨터를 조금씩 만져보려 하니 힘들었는데 아주 잘 설명된 게시글을 보고 많은 도움 되고 있습니다.
    앞으로도 계속 포스팅 부탁합니다.

    1. 버튼이 여러 개 있더라도 버튼에 등록할 OnClickListener를 하나만 생성해 두고 공유하기 위해서입니다.

      버튼이 button1부터 button4까지 있는 경우,
      button1.setOnClickListener(cListener);
      button2.setOnClickListener(cListener);
      button3.setOnClickListener(cListener);
      button4.setOnClickListener(cListener);
      이렇게 해두면 버튼을 누를 때마다 cListener의 onClick() 메서드가 실행되는데, 어떤 버튼에서 호출한 것인지를 알려주는 정보가 View v라는 파라미터입니다.

      물론 버튼이 한개 뿐이면 굳이 switch를 사용할 이유가 없습니다.

  5. 이제 안드로이드 처음 해보는데 정말 많은 도움이 되었습니다. 앞으로도 계속 볼게요! 고맙습니다 ㅎㅎ

  6. 안녕하세요… 게임 어플 하나를 개발하려 하는데 진저브레드 API 10으로도 개발 가능할까요? 혼자하는 거라 그리 복잡하지는 않을겁니다. 그리고 API10을 타겟으로하고, 컴파일시 어떤 컴파일러를 사용하는 것이 좋을까요? 위에서는 최신이라고 되어있던데, API10을 사용하니 API10에 해당되는 컴파일러를 사용하는 것이 좋지 않나요???

  7. 실례일 수 있지만, 댓글 수정 기능이 없어서 아래에 하나 더 작성하겠습니다.
    API10을 사용해서 개발을 하려하는데 API10컴파일러 외에 다른 컴파일러를 사용해도 구동에 문제가 없는가요??다른 컴파일러를 사용해도 괜찮다면 최신 컴파일러를 사용하는 것이 더 유리할까요?

  8. 아아.. 하나 더 질문하겠습니다.
    API10을 사용하는데 JAVA SE7을 사용해도 괜찮을까요? 지금까지 SE7을 사용해 왔던지라…

  9. buttonTest.setOnClickListener(cListener);

    이 부분만 적으면 xxxxx(이)가 중지되었습니다. 라고 나옵니다.
    오늘 처음 따라해보는거라 해결이 쉽지가 않네요 ㅠㅠ

  10. 저 뿐반아니라 주변친구들도 만들고 싶은 app이 굉장히 많습니다. 그런데 늘 개발자가 없어 곤란하네요. 보통 개발자 분들은 어디서 일하나요?

  11. textViewTest = (TextView)findViewById(R.id.textViewTest);
    buttonTest = (Button)findViewById(R.id.buttonTest);
    이부분에서 저는
    (R.id.textViewTest);
    (R.id.buttonTest);
    이두군데서 빨간줄이뜨거든요 ㅜ 진짜 이번에 앱 만드는거 배워보려는 컴퓨터공학도생인데 어떻게해야할까요 ㅜ

  12. 이 시리즈 에러가 많이 납니다. 아마 버전 문제인지도 모르겠네요. 배우실 분 참고하세요.

답글 남기기

이메일 주소는 공개되지 않습니다.