Android Document  SDK old PDF 파일
안드로이드 NotePad 애플리케이션 작성 예제 2
작성자
작성일 2008-03-04 (화) 14:08
ㆍ추천: 0  ㆍ조회: 17174      
IP: 221.xxx.120
※ 아래의 글은 Android Wave와 카페통합을 통해 이곳으로 이동된 글임을 알려드립니다.
 
작성일시 : 2007.11.20 22:42
작성자 : 행복가득(siriusme)
 
Notepad Application 작성 실습 예제 2

♦ 준비 사항
먼저 SDK를 설치하고, Eclipse 개발환경을 맞추어 놓아야한다. SDK를 패키지 내에 우리가 작성해볼 예제에 대한 자료가 있다. 먼저 다음과 같이 실습해볼 프로젝트 파일을 준비하자. 참고로 완전한 노트패드는 SDK의 samples 폴더에 들어 있다.

1. project exercises archive (.zip) 에서 예제를 다운받자.
2. 적당한 위치에 압축을 풀자.
3. NotepadCodeLab 폴더를 연다. 이 파일 안에는 다음과 같은 6개의 프로젝트 폴더를 볼 수 있다.
 
Notepadv는 실습할 프로젝트이고, NotepadSolution은 실습에 대한 해답이다. 연습을 하다 막히는 부분이 있으면 Solution을 보면 된다. 실습해볼 과제는
(1) 실습 1
수정할 수는 없지만 추가할 수 있는 간단한 노트 리스트를 만드는 것. 이것은 ListActivity와 메뉴 옵션을 생성하고 다루어 보며, SQLite 데이터베이스에 노트를 저장하게 될 것이다.
(2) 실습 2
애플리케이션에 두번째 Activity를 추가해본다. 새 Activity를 만들어 AndroidManifest.xml 파일에 추가하고, Activity간 데이터를 전달해해본다. 그리고 더 다양한 화면 레이아웃을 이용하고, startSubActivity() 메소드를 이용하여 비동기적으로 다른 Activity를 호출해본다.
(3) 실습 3
Life-cycle 이벤트에 대한 핸들링을 애플리케이션에 추가하고, Life-cycle을 지나는동안 애플리케이션 상태를 유지하는 방법에 대해 알아본다.
(4) 실습 4
이클립스 디버거를 어떻게 사용하는지, 이것으로 만들어진 lifecycle 이벤트를 어떻게 확인하는지 살펴본다.
♦ 실습 2
(1) 이클립스에서 다음과 같이 노트패드2 프로젝트를 연다.
 
a. Package Explorer에서 오른쪽 클릭을 하고, Import를 선택 후, /General/Existing Project into Workspace를 선택
b. browse 버튼을 클릭하고, 방금전에 다운받은 폴더를 찾은 다음, Notepadv1을 선택하고 OK를 클릭한다.
c. Notepadv2가 위쪽 그림과 같이 추가 된 것을 확인할 수 있다.
d. 만약에 AndroidManifest.xml 파일이나, 다른 문제가 발생하면 project의 오른쪽 클릭을 하고 Android Tools  Fix Project Properties를 선택한다. 이렇게 하면 프로젝트는 라이브러리 파일의 잘못된 위치를 찾고, 에러가 없어진다.
(2) 먼저 Notepadv2 클래스의 onCreate() 메소드를 살펴보면, 실습예제1에서 입력한 것과 차이가 없다는 것을 확인 할 수 있을 것이다. 메뉴에 Delete를 추가해보자. onCreateOptionsMenu()에 다음 코드를 추가하자. menu.add(0, DELETE_ID, R.string.menu_delete);
 
(3) onMenuItemSelected() 메소드에서 DELETE_ID에 대한 새로운 case를 다음과 같이 추가하자.
 
a. 여기서는 ListAdapter의 getSelection() 메소드를 이용하는데, 이것은 리스트에서 현재 선택된 note가 어떤 것인지를 확인하는 것이다.
b. 다음으로 rows 필드에서 선택된 row를 가져와서 rowId를 반환하면, DBHelper에서 해당 row를 삭제하게 된다.
c. 다음으로 fillData()를 호출하여 다시 리스트를 업데이트한다.
 
(4) 다음으로 createNote() 함수를 바꿔볼 것인데, NoteEdit 클래스를 이용하여 노트를 추가(ACTIVITY_CREATE)하기 위해서 새로운 Intent를 생성하고. startSubActivity()를 이용하여 Intent를 실행시켜 볼 것이다. 아래와 같이 코드를 추가하자.
코드를 추가하면 NoteEdit 클래스가 아직 정의되지 않아서 에러 표시가 날 것이다.
 
(5) 이제 onListItemClick() 메소드를 오버라이드 하자. onListItemClick()은 사용자가 아이템을 리스트로부터 선택할 때 호출되는 메소드이다. 이 메소드는 이 메소드를 호출한 객체, 클릭된 ListView내의 View, 클릭된 리스트의 position, 클릭된 아이템의 rowItd를 인자로 받는다. 여기서는 앞의 두 파라메터와 rowId는 무시할 수 있다. 여기서 관심을 가져야 할 부분은 사용자가 선택한 position이며, 이것을 가지고 row로부터 데이터를 불러올 것이다. 그리고 NoteEdit activity에 전송하기 위해 이것들을 묶을 것이다.
 
이 메소드는 NoteEdit클래스를 이용하여 노트를 수정하기 위해 Intent를 생성하고 Intent에 정보를 전달할 수 있도록 데이터를 추가할 것이다. 여기서는 타이틀과 내용, 수정하는 노트의 rowId를 보낼 것이다. 마지막으로 Intent 클래스의 startSubActivity() 메소드 호출하여 실행되도록 한다.
 
a. 여기서는 타이틀과 내용, 수정하고자 하는 노트의 rowId를 전송하기 위해 Intent의 extra를 추가한다. 그리고, NoteEdit클래스의 Intent ACTIVITY_EDIT를 실행한다.
b. putExtra() 메소드는 extra bundle에 아이템을 추가하는 메소드이다.

(6) 위의 createNote()와 onListItemClick() 메소드는 비동기적인 Intent 호출이다. 이제 onActivityResult()를 수정하여 핸들러를 추가하자.
 
onActivityResult()는 서브 Activity가 종료되어 리턴 될 때 호출된다. 파라메터는 다음과 같다.
 requestCode : Intent 호출시 기술한 원본 요청 코드이다. 여기서는 ACTIVITY_CREATE 또는 ACTIVITY_EDIT가 된다.
 resultCode : 호출후의 결과 코드이다. 이것은 모든 것이 정상적으로 완료 되었다면 0을 리턴한다. 그러나 0 이외의 값은 무엇인가 실패 했다는 것을 가르킨다. 표준 결과 코드가 준비되어 있으며, 원한다면 특정 문제에 대해 상수를 추가할 수 있다.
 data : 이것은 결과에 대한 정보를 간단한 텍스트로 리턴할 경우에 쓰인다. (예를 들어 사용자가 다이얼로그로부터 입력한 값 같은 것이다.) 이것은 리턴할 값이 하나이고 스트링일 경우 유용하다. 만약에 더 많은 값을 리턴해야 할 경우는 bundle을 써야한다.
 extras : 이것은 호출된 Intent에서 다수의 결과값을 extra bundle로 리턴 해주는 것이다.
startSubActivity()와 onActivityResult()는 비동기적인 RPC(remote procedure call) 같은 것이며, Activity들이 서로 서비스를 공유하기 위한 방법으로 추천하는 방식이다.
 
a. 이 메소드에서 ACTIVITY_CREATE와 ACTIVITY_EDIT activity 결과를 핸들링한다.
b. 생성의 경우 타이틀과 내용을 extra로부터 꺼내오고 새로운 노트를 만들기 위해 이것을 사용한다.
c. 수정이 경우, 마찬가지로 rowId를 가져오고 이것을 database내의 노트를 수정하는데 사용한다.
d. 모든 작업이 끝나면 fillData()를 호출하여 리스트를 업데이트 한다.
(7) note_edit.xml 파일을 살펴보자. 이것은 Note Editor에 대한 UI 코드이다. 여기에는 우리가 지금까지 보지못한 새로운 android:layout_weight(여기서는 값을 1로 주었다.) 파라메터가 있다. Layout_weight는 LinearLayout에 “importance”를 할당하도록 한다. 모든 view는 layout_weight가 0이 기본 값으로 되어있다.  0은 화면상에 출력될 수 있는 공간만큼의 영역을 차지하고 있다는 것을 의미한다. 즉 그려질 수 있는 개체의 크기만큼만 공간을 차지한다. 0보다 큰 값을 넣을 경우 view의 layout_weight 값과 현재의 레이아웃에 기술한 layout_weight 전체의 비율에 의해 parent의 가용한 공간이 분할된다.
예를 들면 : 텍스트 레이블과 두개의 텍스트 에디트 view가 수평 row에 있다고 하면, 레이블은 layout_weight 값이 없으므로, 그를 영역에 최소 공간만 차지한다. 만약에 두 텍스트 에디트 view의 layout_weight값을 1을 설정할 경우 parent의 남아있는 가로 영역은 똑 같은 비율로 두개로 나누어 진다. 만약 하나의 layout_weight는 1이고 다른 하나의 layout_weight는 2라면 첫번째는 1/3만큼, 두번째는 2/3만큼 공간을 차지할 것이다.
이 레이아웃은 어떻게 다수의 레이아웃내에 서로가 배치되면서 더 복잡한 레이아웃을 나타내는지 보여준다. 이 예제에서는 수평 linear layout이 타이틀 레이블과 텍스트 필드를 수직 레이아웃 내에 수평되게 배치한다.
 
(8) 이제 android.app.Activity를 확장하여 NoteEdit 클래스를 생성해보자. 이것은 안드로이드 이클립스 플러그인 없이 activity를 생성하는 첫번째 코드가 될 것이다. 이렇게 할 경우 onCreate() 메소드는 자동으로 오버라이드 되지는 않을 것이다. 보통 Activity가 onCreate()를 오버라이드 하지 않는다고 생각지 않기 때문에 이 부분부터 먼저 해야 한다. (right click시 override/implement methods 옵션이 이클립스 에디터에서 제공된다.)
 

a. com.google.android.demo.notepad2 패키지를 패키지 익스플로러에서 선택하고, New  Class 팝업 메뉴를 선택하자.
b. Name 필드에 NoteEdit 입력
c. Superclass 필드에 android.app.Activity 를 입력(Activity만 입력하고 Ctrl + Space를 누르면 자동으로 입력됨)
d. Finish를 누른다.
e. NoteEdit 클래스가 에디터로 열고, 에디터 윈도우에서 오른쪽 클릭 Source  Override / Implement Methods… 선택
f. 다이알로그에서 onCreate(Bundle)을 체크하고 Next를 누른다.
g. OK 버튼을 누른다.

(9) onCreate() 메소드를 구현해보자. 여기서는 “Edit Note”(strings.xml에 정의한 스트링)로 불리는 Activity를 만들고, note_edit.xml 레이아웃 파일의 content view를 만든다. 다음에 타이틀과 내용 view, confirm 버튼을 핸들을 얻고, 노트 타이틀과 본문을 set/get하는데 사용한다. Confirm 버튼에 사용자가 누를 때의 이벤트를 붙인다.
 
그 다음에 호출되는 Intent내의 extra bundle로부터 activity로 보내는 값들을 받아오고 타이틀과 내용 수정 view에 내용을 수정할 수 있도록 값들을 미리 넣어둔다. 사용자가 수정하는 노트가 어떤 것인지 알기 위해 rowId도 저장하고 가져온다.
a. 다음과 같이 layout 값을 넣어준다.
 setContentView(R.layout.note_eidt);
b. 버튼 밑 에디터 컴포넌트를 가져온다. 이것은 R 클래스의 id로 찾을 수 있으며, View type으로 캐스팅한다.
 titleText = (EditText)findViewById(R.id.title);
 bodyText = (EditText)findViewById(R.id.body);
 Button confirmButton = (Button)findViewById(R.id.confirm);
* titleText와 bodyText는 멤버 변수이므로 클래스 상단에 선언해주어야 한다.
d. Long rowed private 필드는 수정될 현재의 rowId가 있을 경우 사용된다.
e. title, body, rowId를 Intent내의 extra bundle로부터 가져와 초기화 하는 코드를 넣는다.
 rowId = null;
 Bundle extras = getIntent().getExtras();
 If (extras!=null) {
  String title = extras.getString(Notepadv2.KEY_TITLE);
  String body = extras.getString(Notepadv2.KEY_BODY);
  rowed = extras.getLong(Notepadv2.KEY_ROW_ID);
  if (title!=null) titleText.setText(title);
  if (body!=null) bodyText.setText(body);
 }
f. 버튼의 onclickListener() 함수를 만든다. UI 구현에 있어서 리스너는 좀 더 어려운 요소가 될 수 있지만 여기서 해볼 것은 간단하다. 우리가 원하는 것은 onClick() 메소드를 사용자가 confirm 버튼을 누르는 순간 호출하는 것이고, 이것을 이용해서 수정된 노트의 값을 Intent 호츨자에게 리턴해주면 된다.
 confirmButton.setOnClickListener(new View.OnClickListener() {
  public void onClick(View view) {
  }
 });
 
 
 

(10) onClick 메소드를 구현하자. 이것은 사용자가 confirm 버튼을 클릭했을 경우 실행하는 코드이며, 타이틀과 본문 텍스트를 edit text 필드로부터 가져와서 bundle에 저장한 다음, Intent를 처음 호출한 Activity로 다시 보내주는 메소드다. 만약 노트 생성 대신에 에디트를 하고 있다면 rowId를 bundle에 추가하고 바뀐 것들이 Notepadv2 클래스에 저장되도록 한다.

a. bundle 을 생성하고 타이틀 및 본문 텍스트를 Notepadv2에서 key로 선언한 상수를 이용해서 값을 넣어준다.
 Bundle bundle = new Bundle();
 bundle.putString(Notepadv2.KEY_TITLE, titleText.getText().toString());
 bundle.putString(Notepadv2.KEY_BODY, bodyText.getText().toString());
 
 if (rowed!=null) {
  bundle.putLong(Notepadv2.KEY_ROW_ID, rowed);
 }
  
b. bundle 및 결과 정보에 대한 값을 설정하자. setResult() 메소드는 결과 코드를 설정하기 위해 사용되고, 스트링 데이터, extra bundle을 Intent caller에게 보내주는 역할을 한다. 모든 작업이 끝나면 RESULT_OK를 결과코드로 리턴할 것이다. 여기서는 스트링 데이터 필드는 사용하지 않으므로 null을 리턴하고, 여기서 생성한 bundle은 함께 리턴해주도록 한다.
c. finish() 호출은 activity가 끝났음을 알려주는 것이고, Result에 설정한 값들이 호출자에게 보내진다.
 setResult(RESULT_OK, null, bundle);
 finish();
 
(11) 마지막으로 새 activity를 manifest 파일에 정의한다. 새 activity가 안드로이드에 의해 보여지기 전에 AndroidManifest.xml 파일의 activity entry를 필요로 한다. 이것은 시스템이 해당 activity가 존재하고 호출될 수 있도록 하는 작업이다. 여기에 activity에서 구현한 어떤 IntentFilter가 있는지 정의할 수 있지만, 현재로는 Activity만 정의하도록 한다.
 <activity class=”.NoteEdit”/>

(12) 이제 실행하여 결과를 살펴보자.
 
  

실습 3은 다음 문서에서 진행하도록 한다.
이름아이콘 꿈속에서
2008-11-04 19:00
위 예제 다운로드 링크 입니다.
http://code.google.com/android/intro/codelab/NotepadCodeLab.zip
   
이름아이콘 와이드오픈
2009-02-16 15:47
헉! 1번 예제는 어디 있나효!! ㄷㄷㄷ
난! 소심하니까!
   
이름아이콘 스카이
2009-03-18 10:06
예제파일 다운로드 가능한 변경된 URL입니다
http://developer.android.com/guide/tutorials/notepad/codelab/NotepadCodeLab.zip
   
이름아이콘 음냐쿨쿨
2009-12-04 18:30
오.. 1번 예제도 알려주세요. 안드로이드의 '안'자도 모른답니다..
   
 
덧글 쓰기 0
3500
※ 회원등급 레벨 0 이상 읽기가 가능한 게시판입니다.