www.seuwl.tistory.com

Download Report

Transcript www.seuwl.tistory.com

* 프로그램 설치 (1/4)
기초
JDK(Java Development Kit) :
Android SDK :
Eclipse :
java.com <JRE환경>
developer.android.com
eclipse.org
Eclipse plug-in for Android Development
: dl-ssl.google.com/android/eclipse(책 34p)
1) 15.7 MB
2) 22.3 MB
3) 190 MB
4) 50 MB
* 프로그램 설치 (2/4)
1.
각 사이트에서 프로그램 다운로드 (파일 3개)
2. JDK는 설치, eclipse는 적당한 폴더에 압축 해제
(주의할 사항 : 폴더에 한글이 들어가면 인식 불가한 경우가 있음
따라서 C:\android_test\식의 폴더 생성 후 압축 해제)
3. Android SDK 는 eclipse를 해제한 폴더 상위폴더에 압축 해제
기초
* 프로그램 설치 (3/4)
4. 설치가 완료된 모습
(SDK와 Eclipse폴더)
5. Eclipse는 무설치
이므로 폴더에서
eclipse.exe 파일 실행
7. Help > Install New Software
8. Add 클릭 후 책 34p의 주소를
입력하여 Pending...에서 기다림
9. Developer Tools가 나오면 체크
후 Next 클릭
* 프로그램 설치 (4/4)
4. 안드로이드 관련 플러그인
목록. 저작권 계약 동의를
위해 I accept.. 클릭 후
Finish 선택하면 설치 완료
5. 마지막으로 안드로이드 SDK
설치를 위해 Windows 메뉴 >
Preference 클릭
6. 왼쪽 목록에서 Android 선택 후
SDK Location에 아까 압축을
해제했던 Android SDK
폴더를 선택 후 OK를 누르면
모두 설치 완료
* Android 가상기기 세팅
1. [ p34~35 ]
두 가지 방식이 있는데 첫째, 책 내용
으로 command에서 작업을 위해
환경변수 설정을 해주어야 한다.
그 후 p36의 명령어 입력 :
android create avd –n base1.5 –t 2
2.
대부분 Windows base
이므로 윈도에서 세팅방식은
Windows메뉴 > Android SDK
and AVD Manager 클릭
3. Create new AVD 클릭 후 Name에
책대로 base1.5 입력 후 Create
AVD를 클릭하면 AVD가 생성된다.
4. Base1.5 선택 후 Start
* 주요 내용 [1-3장] (1/3)
1. 개요
- 안드로이드는 구글에서 만든 휴대폰용 오픈 프레임워크
로서 자바 언어 베이스이다.
- 일반 프로그램 언어와 다른 몇 가지는 화면 크기가 작고
키보드, 포인팅, 메모리, 처리속도의 제약 등이 있다.
2. 안드로이드 프로그램 구조
1) Activity : 눈에 보이는 대화상자 등의 인터페이스
2) Content Provider : 내용을 제공한다는 뜻으로
프로그램 처리 데이터 인터페이스
3) Intent : 윈도우의 ‘메시지’와 같은 개념으로 실시간
이벤트를 위한 구성요소이다.
* 주요 내용 [1-3장] (2/3)
기초
4) Service : 역시 윈도우의 서비스와 같은 개념으로
핸들 프로세스. 보이지 않고 작동하는 요소
3. 안드로이드에서 사용 가능한 구성 요소
1) 데이터 보관 : 말 그대로 어플리케이션 처리를 위한
각종 데이터를 내/외부 메모리에 보관
2) 네트워크 : 자바 소켓부터 다양한 네트워크 기능 제공
3) 멀티미디어 : 음악재생, 사진촬영, 음성메모 등의 기능
4) GPS : 지도 등 각종 위치관련서비스를 위한 기능
5) 전화 : 휴대용 폰의 가장 기본적인 기능
* 주요 내용 [1-3장] (3/3)
기초
4. 디렉토리 설명 (루트 + 기타)
1. 루트 디렉토리
- AndroidManifest.xml : 어플리케이션 자체와 포함된
컴포넌트를 정의하는 핵심파일
- Build.xml : 코드 컴파일, 가상기기 설치기능의 핵심파일
2. Src 폴더 : 실제 자바 소스 (.java)
3. Res 폴더 : 대표적으로 GUI Layout 정보를 담는다.
(주로 xml의 형태로 구성된 파일들)
4. Bin 폴더 : 바이너리로 코딩된 파일들(컴파일된 결과)
[3장] 매니패스트 파일 소개
1. 기본적으로 시스템이 자동 생성
2. 권한(퍼미션), 기본 연동 요소(엘리먼트), 어플리케이션 정보
3. 각 장에서 세부 구성내용이 소개됨
* 안드로이드 프로젝트 생성 (1/2)
프로젝트 생성법은 두 가지가 있는데
안드로이드 플러그인이 설치된
이클립스 IDE상에서는 File > New >
Project > Android Project 클릭
Cmd를 이용하는 방법은 책 34p에
소개된대로 환경변수에 tools 폴더를
Path에 지정해주고, activitycreator
명령을 이용한 생성
Ex>
Activitycreator –out (폴더지정)
/path/to/my/project/dir
Com.commonsware.android.Now
(프로젝트명 지정)
4장
5장
6장
* 안드로이드 프로젝트 생성 (2/2)
Create project from existing source를
선택하여 commonsware.com에서
받은 소스폴더를 선택할 경우에
AndroidManifest.xml 파일이 항상
루트에 있어야 한다.
(책 41p에 나온 내용으로 매니패스트
파일이 안드로이드 어플리케이션의
중심이 된다.)
Confer>
오른쪽 화면 밑줄친 부분은
매니패스트 파일이 없을경우 나오는
에러메세지임
4장
5장
6장
* 시간표시 액티비티 분석 (1/4)
받은 소스코드를 풀어 적당히 위치후
안드로이드 프로젝트를 생성한다.
API 레벨은 7, 안드로이드 버전은
2.1이 기본으로 설정되어있다.
주의할 점으로 Now.java 맨 앞에
기술되는 package 구문에서
패키지 이름은 프로젝트 생성시
패키지 이름과 같아야 하는데
이클립스+안드로이드플러그인을
사용할 경우 자동으로 설정된다.
다음장에서, Now.java 구문을
하나하나 살펴보면…
4장
5장
6장
* 시간표시 액티비티 분석 (2/4)
4장
5장
6장
[ 소스폴더\Skeleton\ Now\src\com\commonsware\android\skeleton ]
* 시간표시 액티비티 분석 (3/4)
[ Now.java 소스 설명 (책 51~54p) ]
4장
5장
6장
* 시간표시 액티비티 분석 (3/4)
[ 최종적으로 실행되는 모습 (2pics) ]
4장
5장
6장
* XML 과 안드로이드 (1/4)
4장
5장
6장
★ XML이란 ?
eXtensible Markup Language : 확장성 있는 마크업 언어(데이터 언어)
-
HTML(HyperText ML)과 구조가 유사
상당히 구조적이고 텍스트로만 구성되어 있다.
방대한 량의 데이터를 구조화 시키는데에 용이함
용량을 획기적으로 줄일 수 있다 : XML로 기술 후 컴포넌트zip으로 압축하여 활용
(책의 소스 용량 전체 1.18MB)
★ 대표적으로 이용되는 곳은?
1) OOXML(Office Open XML) : MS 오피스 2007부터 적용 (pptx, docx..)
한컴오피스 2010부터 적용 (한쇼, 한셀..)
2) RSS 피드 : 블로그 등의 웹 게시물을 XML 구조에 맞추어 재생산하여
실시간으로 게시물 확인, 정리, 배포 등이 가능
3) X HTML : HTML의 진보된 형태로 Flash 등을 대체할 HTML 5.0의 기술 중 하나
* XML 과 안드로이드 (2/4)
4장
5장
[ XML 구조의 Microsoft Office 2007 System (화면은 PowerPoint 2007) ]
6장
* XML 과 안드로이드 (3/4)
4장
5장
[ Layouts 예제 폴더의 res/layout/ 내의 main.xml ]
★ 자바 코드와 연결하기 위해서는? (책 61p)
이와 같이 xml 파일을 res(ources)/layout/main.xml 폴더에 넣어 두고,
액티비티를 구성한 Now.java 내의 onCreate() 메소드에
setContentView (R.layout.main);
라고 적어주면 된다.
Confer>
R.java : 이 파일을 통해 레이아웃에 접근하도록 자동 생성된 자바 코드파일
6장
* XML 과 안드로이드 (4/4)
4장
5장
6장
[ XML로 버튼 인스턴스를 정해준 NowRedux 어플리케이션의 실행모습 = 같다 ]
* 기본 위젯 (1/2)
4장
5장
6장
★ 직접 자바 코드에 위젯 관련 인스턴스들을 기술해도
되지만, 국제화의 필요성 때문에 XML 레이아웃을
불러다 쓰는 편이 간편하고, 깔끔한 구성이 된다. (책 65p)
★ 6장 ‘기본 위젯’의 내용은?
레이블, 버튼, 이미지, 입력필드, 체크박스, 라디오버튼 등 각종
위젯들의 자바 + XML 코드 기술법과 속성들을 알아보고,
이러한 GUI 관련 인스턴스를 만드는 클래스의 상위 클래스인
View의 1) 공통적인 속성과 2) 유용한 메소드에 대하여 알아본다.
* 기본 위젯 (2/2)
4장
5장
6장
★ View 클래스의 유용한 속성
- android.visibility : 화면 표시 여부
- android.background : 위젯 배경색 지정
★ View 클래스의 유용한 메소드
- setEnabled() : 특정 위젯의 사용 가능여부 확인
체크박스 선택시 다른 위젯 사용여부 변경 등에 쓰임
- requestFocus() : 입력 포커스를 해당 위젯으로 옮기기
- getParent() : 상위 위젯을 알려줌
- findViewByld() : 컨테이너 내부에 지정한 ID에 해당하는 위젯 찾기
* 컨테이너 개념
7장
8장
<LinearLayout><RelativeLayout><TableLayout>
<RadioGroup>
<RadioButton>
</>….</>
9장
* 1> Linear(직선)Layout 클래스
7장
8장
방향(Orientation)
• 가로 : Horizontal / 세로 : Vertical
채우기(Fill model)
• Layout_width·height / Wrap_content / Fill_parent
• 위젯 폭 직접 지정 / 내용에 맞추어(필요한 만큼) 차지 / 남은 공간(모두) 차지
가중치(Weight)
• 두 개의 위젯의 경우 : Fill parent로 100% 배치 후, layout_weight 비율 지정
그래비티(Gravity)
• 기본적으로 왼쪽 상단정렬 / layout_gravity → left, center_horizontal, right
패딩(Padding)
• Padding + Top, Bottom, Left, Right (위젯과 위젯 셀의 관계 픽셀단위로 지정)
9장
* 1> Linear(직선)Layout 클래스
7장
8장
[ res/layout/main.xml에서 Radiobutton/text 속성 변환 후 실행한 모습 ]
9장
* 2> Relative(관계)Layout 클래스
7장
8장
컨테이너 기준으로 배치
• Layout_alignParent…TBLR / 값은 true or false
기준 위젯 표시
• Android:id=@+id/[NAME] ← 피참조 위젯명 지정
별도의 위젯을 기준으로
• Layout_above, below, toL/Rof + alignBaseline(기준선일치)
참조 순서에 대하여
• 위부터 읽기 때문에 1. 아래에 정의된 것을 위에서 참조 불가능
2. 위에서 레이아웃 속성을 지정할 경우 아래의 정의를 침범할 수 있음
9장
* 3> Table(표)Layout 클래스
7장
8장
TableLayout
• 행 : TableRow 인스턴스로 추가
• 열 : 안드로이드 시스템이 자동으로 생성
행 안에 들어가지 않는 위젯
• TableRow가 아닌 일반 위젯이 들어갈 경우엔
세로 LinerLayout으로 인식
• 폭이 fill_parent이므로 HTML의 <HR>처럼 한 행을 채움
9장
* 2+3> Relative, TableLayout
7장
8장
파란색 선은 View 엘리먼트를
TableLayout밑에 넣어 일반
위젯처럼 처리되게 한 모습
[ URL 부분은 5px의 padding이 설정된 컨테이너, baseline으로 관계됨 ]
9장
* 4> 스크롤(Scroll)
<ScrollView>
• 원하는 기존 레이아웃을 스크롤뷰 컨테이너로
감싸면 자동으로 스크롤 기능 활성화
7장
8장
9장
* 공통의 인터페이스 ‘어댑터’
7장
8장
어댑터(Adapter;접속소켓)란?
안드로이드에서 말하는 어댑터 :
선택기능을 제공하는 선택 위젯에서
사용할 값의 목록을 공통으로 지정
즉, 여러개의 같은형(text, list…)의 다른 정보(배열마다)를
특정 View에 저장하고 보여 주기 위해서
어댑터라는 클래스를 이용해 View와 정보를 연결함
9장
* Array(배열)Adapter 클래스
7장
8장
9장
[ArrayList를
ArrayAdapter의
생성자배열)
메소드 값 ]
만든다. (텍스트
*
*
*
this
: 일반적으로ArrayList를
액티비티를연결한다.
가리킴
ArrayAdapter에
android.R.. : 리소스 ID (안드로이드 내장)
items
: 1번에
지정한 ArrayList
TextView에
아답터를
연결한다.배열
(실제이름
set)
ArrayList<String> items = new ArrayList<String>();
ArrayAdapter<String> wow =
new ArrayAdapter(this, android.R.layout.simple_list_item1, items);
TextView.setAdapter(wow);
* 리스트 예제 소스 분석 (p.107~8)
7장
8장
9장
* 리스트 예제 실행 모습 (p.108)
7장
8장
배열에 입력된
글자들이 리스트화
되어 나타나고,
클릭하면 레이블에
표시된다.
(onListItemClick 이벤트)
9장
* 스피너(Spinner)예제 실행 (p. 111)
7장
8장
리소스 ID를
simple_spinner_item
으로 바꾸어 주면
자동으로 드롭다운
목록화 되어 나타남
(화살표 표시여부 :
drawSelectorOnTop)
9장
* 그리드(Grid;격자무늬)
7장
8장
9장
Res/layout/main.xml 에서 그리드뷰 정의
GridView에서는
행은 양에 따라
시스템이 자동으로
지정한다.
(열 관련 값만 조정)
Column : 위젯이
Spacing : 빈공간이
* 자동완성 (Auto_Complete) (1/3)
7장
8장
[ 네이버의 자동완성 기능 / 안드로이드의 자동완성 기능 = 같다 ]
9장
* 자동완성 (Auto_Complete) (2/3)
7장
8장
9장
Confer>
Threshold : 한계점
Override : 상속받은 후
재정의하여 사용
AutocompleteDemo를 오버라이딩하여
윈도우를 생성하고(onCreate(B…)
Editbox를 정의하고 마지막으로
Dropdown_item 속성의 리소스ID로
ArrayAdapter 생성(자동완성 개체 생성)
* 자동완성 (Auto_Complete) (3/3)
7장
on
TextChanged
before TextChanged 3가지 메소드
after
TextChanged
8장
9장
* 리스트 고급활용 – 간단예제 (1/2)
7장
8장
9장
[ Row.xml 내용 ]
LinearLayout으로
가로 선을 정의후
① 아이콘과(icon)
② 라벨(label)을
차례로 두어 이전의
밋밋한 리스트보다
훨씬 나은 모습으로
보임
※ 그러나 main.xml
과는 다르게
실제 소스에서
불러주어야
시스템이 인식함
* 리스트 고급활용 – 간단예제 (2/2)
[ StaticDemo.java 내용 ]
일반적인 ListView 어플리케이션과 거의 동일한
구조이다. 다른 부분은, ArrayAdapter 생성시
③ R.layout.row 전용 레이아웃 사용을 기술한
부분이다. 만약, row.xml을 불러오고 싶으면,
R.layout 뒤에 .[NAME] 식으로 기술하면 된다.
7장
8장
9장
* 리스트 활용 – 인플레이션 (1/3)
7장
8장
9장
★ 인플레이션 : XML레이아웃을 분석해 View 트리 구조를 생성하는 것
01
@Override
02
public void onCreate(Bundle icicle) {
03
super.onCreate(icicle);
04
setContentView(R.layout.main);
05
setListAdapter(new IconicAdapter());
06
selection=(TextView)findViewById(R.id.selection);
07
}
// View 객체 생성(onCreate..)
08
09
public void onListItemClick(ListView parent, View v, int position, long id)
10
{ selection.setText(items[position]); }
// 리스트의 아이템을 클릭하면,
11
해당 객체의 ID를 찾아 (06줄) selection
12
선택된 ID에 해당하는 배열의 아이템을
13
표시해줌 (setText)
* 리스트 활용 – 인플레이션 (2/3)
14
public View getView
15
(int position, View convertView, ViewGroup parent)
16
{
7장
8장
9장
// 실제 View 생성 부분(getView)
// 인플레이션 구성 메소드
17
LayoutInflater inflater=getLayoutInflater();
18
View row=inflater.inflate(R.layout.row, parent, false);
19
TextView label=(TextView)row.findViewById(R.id.label); // label 생성시 해당 ID찾기
// row(행) View를 생성시,
// row.xml을 활용하는 인플레이션
20
21
label.setText(items[position]);
[ 텍스트 구현 ]
22
23
ImageView icon=(ImageView)row.findViewById(R.id.icon); // 아이콘 생성시 해당 ID찾기
24
25
if (items[position].length()>4) {
26
icon.setImageResource(R.drawable.delete);
27
}
28
else {
29
icon.setImageResource(R.drawable.ok);
30
}
[ 이미지 구현 ]
// 아이템의 텍스트 길이가 4이상이면
// delete항목을 그려라.
// 아니면, ok 항목을 그려라
31
32
33
return(row);
// 최종적으로 getView에 값을 리턴
* 리스트 활용 – 성능 개선 (1/3)
7장
8장
9장
[ ConvertView ]
getView() 메소드 사용시
두 번째 인자로 받는 값
이는 두 가지 값을 가진다.
.Convert
View
.Find
View
byID
*리소스
절약
*코드의
간소화
1. Null (없음)
2. 바로 이전의 객체
★ 필요한 이유, 과정?
ListView의 행(row)이
매번 getView를 호출하면
불필요한 Layout객체 생성,
XML 레이아웃 호출 등
리소스 낭비가 있다.
만약, row의 레이아웃이
이전 객체와 같다면,
convertView를 활용해
불필요한 재코딩을 방지.
* 리스트 활용 – 성능 개선 (2/3)
7장
8장
9장
[ FindViewbyID ]
rowView내부에서 수정할
위젯의 ID를 추출해냄
setTag / getTag
.Convert
View
.Find
View
byID
*리소스
절약
*코드의
간소화
1. setTag : ID 저장
2. getTag : ID 호출
★ 필요한 이유, 과정?
convertView와 마찬가지,
중복된 오버헤드를
줄이기 위해 ‘홀더패턴’을
만들어 ID를 getView가
호출되어 text, image등
객체를 만들시마다 호출
하지 않고 보관해둠
(setTag)
* 리스트 활용 – 성능 개선 (3/3)
7장
8장
9장
홀더 패턴을 구성하거나
잦은 중복된 기술을
줄이는 방법 외에도
넓은 의미에서 XML을
이용한 레이아웃의
중복 코딩을 방지하는 것도
.Convert
View
.Find
View
byID
*리소스
절약
*코드의
간소화
CPU의 부하를 덜고
결과적으로 배터리
수명 향상을 가져오게
된다.
즉, 성능 개선은
여러가지 방법이 있고
대체적으로 중복된
코드를 줄임으로서
재연산을 방지
(overhead down)
하는 패턴이다.
* 리스트 활용 – 성능개선 코드분석
7장
8장
9장
[1/2] ConvertView
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
public View getView(int position, View convertView, ViewGroup parent) {
View row=convertView;
// ListView에서 각 행을 생성할 때 호출되는 getView
// convertView값을 row로 파싱
if (row==null) {
// row is null 이면, row.xml에 맞추어 새로 그려준다.
LayoutInflater inflater=getLayoutInflater();
마치 row is null 은 ‘변화 없음’을 의미한다.
row=inflater.inflate(R.layout.row, parent, false);
}
TextView label=(TextView)row.findViewById(R.id.label);
label.setText(items[position]);
ImageView icon=(ImageView)row.findViewById(R.id.icon);
if (items[position].length()>4) {
icon.setImageResource(R.drawable.delete); }
else { icon.setImageResource(R.drawable.ok); }
return(row);
}
// 아직 해당하지 않는 내용이지만
// getView 호출시 findViewByID가
// 불필요하게 n by n 으로 호출된다.
// 이 때, 2번째 홀더패턴으로 해결가능
* 리스트 활용 – 성능개선 코드분석
7장
8장
9장
[2/2] Holder Pattern – FindViewByID (1/2) – ViewWrapper 클래스
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
class ViewWrapper(포장지) {
View base;
TextView label=null;
ImageView icon=null;
ViewWrapper(View base)
{
this.base=base;
}
// ①과 ②에서는, label or icon 변수가 null일 경우만
// findViewByID를 호출, 반대의 경우 저장된 인스턴스
// (해당 ID)를 리턴해주어 오버헤드를 줄인다.
TextView getLabel() {
if (label==null) {
label=(TextView)base.findViewById(R.id.label);
}
return(label);
}
}
ImageView getIcon() {
if (icon==null) {
icon=(ImageView)base.findViewById(R.id.icon);
}
return(icon);
}
* 리스트 활용 – 성능개선 코드분석
7장
8장
9장
[2/2] Holder Pattern – FindViewByID (2/2) – 실제 Demo.java의 getView부분
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public View getView(int position, View convertView, ViewGroup parent) {
View row=convertView;
ViewWrapper wrapper=null;
// wrapper 값 초기화
if (row==null) {
LayoutInflater inflater=getLayoutInflater();
row=inflater.inflate(R.layout.row, parent, false);
wrapper=new ViewWrapper(row);
row.setTag(wrapper);
}
else {
wrapper=(ViewWrapper)row.getTag();
}
// convertView 성능 개선
// row 생성 후 인스턴스(ID)값을 저장
(setTag)
// row is not null 이면, 바로 인스턴스 호출
(getTag)
wrapper.getLabel().setText(getModel(position));
if (getModel(position).length()>4) {
wrapper.getIcon().setImageResource(R.drawable.delete);
}
// 인스턴스(ID)는 ViewWrapper클래스를
else {
// 호출함으로써 얻어지기에 wrapper 이용
wrapper.getIcon().setImageResource(R.drawable.ok);
}
return(row);
}
* 리스트 활용 – More attractive
★ Rating Bar 만들기 – 평점 적용
화면 랜더링
(getView 호출)
Adapter 연결
7장
8장
9장
* 리스트 활용 – RatingBar 소스(1/3)
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
7장
8장
9장
public void onCreate(Bundle icicle)
{super.onCreate(icicle);
ArrayList<RowModel> list=new ArrayList<RowModel>();
for (String s : items) {
list.add(new RowModel(s));
}
// 여전히 String 배열을 이용하지만 ArrayAdapter에
// 넣는 대신에 방금 전에 본 RowModel에 넣음
// 아래의 코드에서 나오겠지만 그것은 Rating, Text로 구성
[ getView ]
public View getView(int position, View convertView, ViewGroup parent) {
View row=convertView;
ViewWrapper wrapper;
RatingBar rate;
if (row==null) {
// row(=convertView) is null 일 경우… 즉, 첫 행을 의미함
LayoutInflater inflater=getLayoutInflater();
row=inflater.inflate(R.layout.row, parent, false);
wrapper=new ViewWrapper(row);
// 홀더 패턴
row.setTag(wrapper);
rate=wrapper.getRatingBar();
// RatingBar 객체를 불러옴
* 리스트 활용 – RatingBar 소스(2/3)
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
7장
8장
9장
RatingBar.OnRatingBarChangeListener l=
new RatingBar.OnRatingBarChangeListener()
{
public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromTouch){
Integer myPosition=(Integer)ratingBar.getTag(); // RatingBar의 해당 행 태그를 읽어옴(getTag)
RowModel model=getModel(myPosition);
// 그리고 Integer로 형변환함
// 이 얻은 위치 번호로 RowModel을 불러옴
// 이 변환된 값이 배열내 위치 번호임
model.rating=rating;
// RowModel에 해당하는 위치에 값을 입력함
LinearLayout parent=(LinearLayout)ratingBar.getParent();
TextView label=(TextView)parent.findViewById(R.id.label);
label.setText(model.toString()); }};
// 다음 슬라이드의 RowModel 클래스에서 언급될 별 3개 이상의 경우대문자화
rate.setOnRatingBarChangeListener(l);
}
else {
wrapper=(ViewWrapper)row.getTag();
rate=wrapper.getRatingBar();
}
// 일종의 재활용 부분 시작.. 첫 행이 아니니까
// 이 두줄은 위에서와 마찬가지로
// RatingBar 변화 감지 부분
RowModel model=getModel(position);
// 위치번호로 RowModel 호출하고,
wrapper.getLabel().setText(model.toString());
rate.setTag(new Integer(position));
rate.setRating(model.rating);
// RowModel 클래스를 통한 평점별 텍스트 변화
return(row); }}
* 리스트 활용 – RatingBar 소스(3/3)
59
7장
8장
[ RowModel ]
60
61
class RowModel {
62
String label;
63
float rating=2.0f;
// rating의 기본값 float(실수)형으로 2.0
64
65
RowModel(String label) {
66
this.label=label;
67
}
68
69
public String toString() {
70
if (rating>=3.0) {
71
return(label.toUpperCase());
72
}
73
74
return(label); }}}
// rating 이 3.0 이상일 경우 toUpperCase(대문자)
9장
* 리스트 활용 – 통합
(p.144~151)
7장
8장
9장
5. 코드 중간에 OnRatingBarChangListener 구현이나 성능 개선을 위한
convertView, Holder Pattern 구현 등 모두 같다. 주의할 것은..
FindViewByID는 ViewRapper 클래스에서 getChildAt로 구현되는데
0과 1의 거짓과 참의 값을 가진다. (그런 식으로 구현, 패턴 알고리즘은 같다)
6. 기초적인 Adapter, Rateable, ViewWrapper를 구현하면 RateListView 클래스가
그것들을 활용하게 된다. 일단 ListView를 상속받은 후 RateableWrapper를
기본 adapter로 세팅해준다. 고작 10줄 내외로 간단하게 구현된 클래스를
활용하여 RatingBar 구현이 가능하다.
7. 추가적으로 활용하자면 RateListView 클래스를 JAR 파일로 묶으면
프로젝트에서 불러와 활용이 가능하므로 OOP로서의 안드로이드 프로그래밍을
최대한 활용할 수 있다.
* 날짜·시간 위젯
10장
11장
이러한 고급 위젯이 필요한 이유?
• 숫자 입력을 받는 부분에서 문자가 입력되는 등의 오류를
막기 위해.. 안드로이드 시스템에서 지원하는 몇 가지 고급
GUI가 있다.
[ DatePicker, TimePicker 위젯의 클래스를 이용한 Dialog box 생성 ]
12장
* 시계, 진행상태 표시 위젯
10장
11장
12장
[ xml에만 정의하고 R.layout.main을 setContentView에 넣어주면 된다 ]
* 날짜·시간 위젯 소스 분석 (1/3)
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
10장
11장
12장
public class ChronoDemo extends Activity {
// 기초적인 컨테이너 및 레이아웃 형성 부분
DateFormat fmtDateAndTime=DateFormat.getDateTimeInstance();
// fmtDateandTime 이라는 이름의 컨테이너를 자바 포맷 날짜취득 getDateTime인스턴스 호출
TextView dateAndTimeLabel;
// 라벨 형성 (날짜, 시간 선택하면 표시해줄 장소)
Calendar dateAndTime=Calendar.getInstance(); // 데이터 모델로 캘린더 객체 사용
DatePickerDialog.OnDateSetListener d=new DatePickerDialog.OnDateSetListener() {
// 날짜변경확인 리스너 생성
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
// 앞으로 자주 쓰일 날짜 설정 클래스 생성
dateAndTime.set(Calendar.YEAR, year);
// 캘린더 데이터 모델에 년도 맞춰주기
dateAndTime.set(Calendar.MONTH, monthOfYear);
dateAndTime.set(Calendar.DAY_OF_MONTH, dayOfMonth);
updateLabel();
// 값을 입력했으면 라벨에 업데이트해라
} };
(맨 마지막에 정의될 클래스)
TimePickerDialog.OnTimeSetListener t=new TimePickerDialog.OnTimeSetListener() {
public void onTimeSet(TimePicker view, int hourOfDay, // 같은 개념으로 시간 맞추어 주는 부분
int minute) {
dateAndTime.set(Calendar.HOUR_OF_DAY, hourOfDay);
dateAndTime.set(Calendar.MINUTE, minute);
updateLabel(); } };
* 날짜·시간 위젯 소스 분석 (2/3)
21
22
23
24
25
26
27
28
30
31
32
33
34
35
36
37
38
39
40
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
10장
11장
12장
// 오버라이딩 받아서 실제 위젯 형성 및 관련 코딩시 사용
// 위젯 생성
// 모양 바꾸려면 main.xml
[ 첫번째 버튼 정의 – 날짜 선택 ]
Button btn=(Button)findViewById(R.id.dateBtn);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
new DatePickerDialog(ChronoDemo.this,
d,
dateAndTime.get(Calendar.YEAR),
dateAndTime.get(Calendar.MONTH),
dateAndTime.get(Calendar.DAY_OF_MONTH)).show();
}
});
[ 두번째 버튼 정의 – 시간 선택 ]
btn=(Button)findViewById(R.id.timeBtn);
// 버튼 생성 (이 버튼은 id가 dateBtn임)
물론, main.xml에 정의되어있음
// 버튼이 클릭되면,
// 날짜 설정 다이얼로그 박스 띄워라
// 만든 리스너를 인자 하나로 받음(d)
// 년
// 월
// 일
* 날짜·시간 위젯 소스 분석 (3/3)
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
10장
11장
12장
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
new TimePickerDialog(ChronoDemo.this,
// 날짜 입력받는 다이얼로그 네임 ‘타임피커’
t,
dateAndTime.get(Calendar.HOUR_OF_DAY),
dateAndTime.get(Calendar.MINUTE),
true).show();
}
});
dateAndTimeLabel=(TextView)findViewById(R.id.dateAndTime);
// 라벨은 텍스트 형식이다. 정의부분.
updateLabel();
// 라벨은 실시간으로 업데이트 된다.
}
private void updateLabel() {
dateAndTimeLabel.setText(fmtDateAndTime
.format(dateAndTime.getTime()));
}
// 라벨의 데이터는 입력받은 값이다.
* 탭(Tab) 위젯 개념
10장
[Tab Widget]
[Tab Widget]
Tab 1
Tab 2
11장
[FrameLayout] – Tab별 Contents
12장
* 탭 위젯 소스 분석 (1/2) : XML
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
10장
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tabhost“
<LinearLayout
<TabWidget android:id="@android:id/tabs“ />
<FrameLayout android:id="@android:id/tabcontent“
<AnalogClock android:id="@+id/tab1“/>
<Button android:id="@+id/tab2“/>
</FrameLayout>
</LinearLayout>
</TabHost>
TabHost > TabWidget > FrameLayout 순으로 정의한 후,
id를 tab[N] 식으로 주며 탭 별 내용을 지정한다.
※ 순서에 유의 (탭호스트>위젯>프레임레이아웃)
11장
12장
* 탭 위젯 소스 분석 (2/2) : JAVA
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
10장
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
// 객체 생성
TabHost tabs=(TabHost)findViewById(R.id.tabhost);
// 탭호스트 정의
11장
12장
tabs.setup();
[ 탭 1 정의 ]
TabHost.TabSpec spec=tabs.newTabSpec("tag1");
spec.setContent(R.id.tab1);
spec.setIndicator("Clock");
tabs.addTab(spec);
[ 탭 2 정의 ]
spec=tabs.newTabSpec("tag2");
spec.setContent(R.id.tab2);
spec.setIndicator("Button");
tabs.addTab(spec);
}
p.168
// 탭은 TabSpec 인스턴스에서
각종 모양을 설정해준다.
// xml에서 tab1 내용을 표시
// 인디케이터 = 표시될 텍스트
// Tabs, setContent, Indicator 앞에 new, add를
// 붙임으로서 리스너와 연결해 동적인 탭 가능
* Flipper(넘기기) 위젯 (p.172)
10장
11장
[ XML ]
<ViewFlipper>
<위젯1..>
<위젯2..>
</ViewFlipper>
[JAVA]
정의 : ViewFlipper
활용 : Flipper.showNext()
[ Fancy/Flipper1 ]
12장
* Flipper(넘기기) 위젯 (p.176)
10장
11장
배열에 단어를 입력 후
지정한 간격에 따라
플리핑되는 예제
[ 구현을 위해 필요한 것은? ]
1. setIn/OutAnimation
(R.anim.push_left_in/out 인자)
2. setFlipInterval = 1000(=1초)
startFlipping (타이머 실행)
2번의 경우 배열의 값을 담는
각 btn들의 for문을 돌린 후에
코딩하여야 한다.
[ Fancy/Flipper2 ]
12장
* 메뉴 종류 - 2가지
옵션 메뉴
(p.180)
10장
11장
컨텍스트 메뉴
컨텍스트 메뉴
(tap-and-hold)
1. ICON 메뉴
2. Extended 메뉴
[ ListView에 메뉴 인스턴스만 추가된 예제 실행 모습 ]
12장
* 메뉴 예제 (옵션+컨텍스트) (1/3)
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
10장
11장
12장
public class MenuDemo extends ListActivity {
TextView selection;
String[] items={"lorem", "ipsum", "dolor", "sit", "amet",
"consectetuer", "adipiscing", "elit", "morbi", "vel",
"ligula", "vitae", "arcu", "aliquet", "mollis",
"etiam", "vel", "erat", "placerat", "ante",
"porttitor", "sodales", "pellentesque", "augue",
"purus"};
public static final int EIGHT_ID = Menu.FIRST+1;
// 픽셀 수정을 위한 정의
public static final int SIXTEEN_ID = Menu.FIRST+2;
public static final int TWENTY_FOUR_ID = Menu.FIRST+3;
public static final int TWO_ID = Menu.FIRST+4;
[ 기초적인 레이아웃 생성 : 객체, 리스트어답터, 컨텍스트메뉴 인스턴스 호출 ]
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
setListAdapter(new ArrayAdapter<String>(this,
//리스트뷰 어답터 생성
의
android.R.layout.simple_list_item_1, items));
selection=(TextView)findViewById(R.id.selection);
// 텍스트 보여질 selection 정
registerForContextMenu(getListView()); }
// 리스트뷰 인스턴스를 넘겨줌
* 메뉴 예제 (옵션+컨텍스트) (2/3)
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
10장
11장
12장
public void onListItemClick(ListView parent, View v, int position, long id) {
selection.setText(items[position]);
// 아이템을 클릭하면 selection이라는
}
방금전에 정의한 textview에 set
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo
menuInfo) {
populateMenu(menu); }
// onCreateContextMenu : 컨텍스트 메뉴 생성
컨텍스트랑 아래의 옵션메뉴는 populateMenu 호
출
@Override
public boolean onCreateOptionsMenu(Menu menu) {
populateMenu(menu);
// onCreateOptionsMenu : 옵션 메뉴 생성
return(super.onCreateOptionsMenu(menu));
}
// 옵션메뉴는 프레임웤에서 시스템 관련 메뉴 항목을
상속받아야 함 (super.onCreateOptionsMenu)
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return(applyMenuChoice(item) || super.onOptionsItemSelected(item)); }
// 옵션과 컨텍스트 각각 선택되면 공통적으로 applyMenuChoice를 호출해 해당 item 값
리턴
@Override
public boolean onContextItemSelected(MenuItem item) {
return(applyMenuChoice(item) || super.onContextItemSelected(item)); }
* 메뉴 예제 (옵션+컨텍스트) (3/3)
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
10장
11장
12장
private void populateMenu(Menu menu) {
// 메뉴별로 호출된(2번) 메뉴 항목 추가 부
분
menu.add(Menu.NONE, ONE_ID, Menu.NONE, "1 Pixel");
menu.add(Menu.NONE, TWO_ID, Menu.NONE, "2 Pixels");
menu.add(Menu.NONE, EIGHT_ID, Menu.NONE, "8 Pixels");
{ 중략 }
}
private boolean applyMenuChoice(MenuItem item) { // 실제로 구분선 두께를 바꾸어 apply
switch (item.getItemId()) {
case ONE_ID:
getListView().setDividerHeight(1);
return(true);
case EIGHT_ID:
getListView().setDividerHeight(8);
return(true);
case SIXTEEN_ID:
getListView().setDividerHeight(16);
return(true);
}
{ 중략 }
return(false);
* 메뉴 인플레이션 (부풀리기)
10장
11장
12장
인플레이션 개념 복습 – 9장 (p.128~30)
*
*
*
*
XML로 개략적인 레이아웃의 정의가 가능하다.
Inflation 기능으로 실제 View 구조를 형성할 수 있다.
getLayoutInflator() 클래스로 실제 구현이 된다.
설계와 관리의 편의성을 위해 인플레이션 한다.
[ java 코드에서 인플레이트(p.193) – res/menu/sample.xml로 지정해줌) ]
* 메뉴 인플레이션(부풀리기)
<Menu>
.
.
.
<Item>
or
<Group>
<item>
.
.
.
순서 지키기
10장
11장
12장
인플레이션은
코드 간단화 측면에서도
요긴하게 쓰이지만
각종 레이아웃 속성을
확인하고 일목요연하게
정리하는데에도 유용하다.
메뉴 인플레이션 관련
속성들(android:[N])
1. 아이콘, 텍스트 가능
2. 활성화 여부 지정
3. 단축키 지정 가능
4. 화면 표시 여부
5. 배치 순서 결정
* 글 꼴 (Fonts) – 소스 분석 (1/2)
10장
11장
12장
* 글 꼴 (Fonts) – 실행 모습 (2/2)
10장
11장
12장
* 단순한 브라우저 생성
01
02
03
04
05
06
07
08
09
10
11
13장
14장
<LinearLayout
xmlns:android="http://schemas
.android.com/apk/res/android"
”>
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
setContentView(R.layout.main);
<WebView
android:id="@+id/webkit"
android:layout_width="fill_parent"
android:layout_height="fill_parent
“ />
browser=(WebView)findViewById(
R.id.webkit);
</LinearLayout>
Uses Permissions
→ INTERNET
browser.loadUrl("http://commons
ware.com");
}
15장
01
02
03
04
05
06
07
08
09
10
11
* 내용표시, 네비게이션 메소드
01
02
03
04
05
06
07
08
09
10
11
<LinearLayout
xmlns:android="http://schemas
.android.com/apk/res/android"
”>
<WebView
android:id="@+id/webkit"
android:layout_width="fill_parent"
android:layout_height="fill_parent
“ />
</LinearLayout>
Uses Permissions
→ INTERNET
13장
14장
public void onCreate(Bundle icicle)
{
[중략]
browser=(WebView)findViewById(
R.id.webkit);
browser.loadData("<html><bo
dy>Hello, world!</body></html>",
"text/html", "UTF-8");
}
15장
01
02
03
04
05
06
07
08
09
10
11
* WebViewClient (1/2)
13장
WebViewClient 인스턴스의 필요성
Application
WebView
작업 과정에서 이벤트 관련 제어권 이양 필요
14장
15장
* WebViewClient (2/2)
13장
14장
15장
WebViewClient 예제 구조 (p.207~8)
• setWebViewClient
(new Callback());
→ 인자받음(0, 1)
객체생성
loadTime()
• New Data()
→ 날짜 표시
shouldOverrideUrlLoading()
• [클릭시이벤트]
1. loadTime()호출
2. true(1) 리턴
(0 시스템 / 1 내부처리)
Callback
일단 loadTime() 호출해 값 생성 후, 어떤 형식으로 처리할지 지정(true, false)
* 팝업 메시지 - 코드 (1/3)
13장
14장
15장
* 팝업 메시지 – 코드 (2/3)
13장
14장
15장
* 팝업 메시지 – 실행 (3/3)
13장
14장
15장
* 스레드 – 개념 (핸들러 O)
13장
14장
15장
Main(Core)
안드로이드
JAVA
XML
Thread
UI(Foreground)
사용자
Manifest
Background
사용자
Android Program
[ 코드상태에서 구조적 측면 ]
[ 실행단계에서 객체적 측면 ]
* 스레드 – 개념 (핸들러 O)
13장
14장
15장
* 스레드 – 개념 (핸들러 O)
13장
14장
15장
Message 객체
• 메시지큐에 쌓는 개념, 쌓인 순서대로 실행
Message
• obtainMessage()를 통해 메시지 일단 확보
• sendMessage() : 메세지큐에 쌓기
• handleMessage() : 메시지 호출하여 쓰기
Handler()
Runnable 객체
• 직접 Handler에게 넘겨주어 실행
(바로 다음슬라이드에서 설명)
• 다양한 종류의 post…() 메소드
Runnable
* 스레드 – 개념 (핸들러 X)
13장
14장
15장
* 스레드 – Source Code
13장
14장
15장
* Confer> 한글 키보드 설정법 (HangulKeyboard.apk)
* Activity Life-Cycle
(1/2)
16장
17장
18장
onCreate(Bundle) -> onStart() -> onResume() -> onPause() -> onStop() -> onDestory()
* Activity Life-Cycle (2/2)
[ SourceCode ]
[ Pause ]
[ Active, Running ]
[ Stop ]
* 환경설정 예제 - 실행화면
[ SimplePrefsDemo.java ]
16장
17장
[ EditPreferences.java ]
18장
* 환경설정 예제 - 실행화면
[ SimplePrefsDemo.java ]
XML – layout/main.xml
16장
17장
18장
[ EditPreferences.java ]
XML – xml/preference.xml
* 환경설정 예제 <XML>
[ xml / preferences.xml ]
16장
17장
18장
[ AndroidManifest.xml ]
1. 환경설정 xml은
PreferenceScreen 으로 시작한다.
2. 체크박스와 같이 설정값이 2개이면
세부 지정항목이 없지만 벨소리와
같은 경우 showDefault / Silent
등을 지정 가능하다.
(안드로이드 디벨로퍼 사이트 참고)
[ layout / main.xml ]
* 환경설정 예제 <JAVA>
16장
17장
18장
[ Main Activity : SimplePrefsDemo.java (1/2) ]
p.30 인텐트(메시지)를
통한 액티비티 생성
[ Sub Activity : EditPreferences.java ]
* 환경설정 예제 <JAVA>
16장
17장
18장
[ Main Activity : SimplePrefsDemo.java (2/2) ]
Confer > 객체 생성 onCreate클래스의 대표적인 메소드 : Bundle / icicle, saveInstanceState
* 환경설정 예제 <JAVA>
16장
17장
Prefs라는 이름을 가진 SharedPreferences 인스턴스를 생성한다.
SharedPreferences 인스턴스에서 환경설정 값을 가져오는 메소드는 2개가 있다 (p. 236)
1. getDefaultSharedPreferences : 안드로이드 시스템 차원에서 설정값 추출
2. get_______SharedPreferences : 어플리케이션 차원에서 설정값 추출
여기서는 1번을 사용하였다. 벨소리나 체크박스 관련 설정은 시스템 설정이므로..
객 체(object)
• 어떠한 물질, 눈에 보이는 ‘무언가’, 사용자와 인터액션 하기위한 ‘행위’와 ‘상태’를 지닌 것
클래스(class), 메소드(method)
• 클래스 : 객체의 세부 정의 부분 / 인스턴스 없이 독자적으로 이루어지지는 못함
• 메소드 : 클래스에서 객체를 정의 할 때 객체가 취하는 행위, 상태에 대한 세부적인 방법
인스턴스(instance)
• 클래스로부터 만들어진 소규모 객체, 이들이 모여 큰 객체의 개념을 형성함 (혼용 가능성)
18장
* 환경설정 – 모양새 갖추기
16장
17장
18장
[ XML 구조 ]
<PreferenceScreen>
<PreferenceCategory>
1. <Checkbox…>
2. <PreferenceScreen>
<Category>
1. “”
2. “”
* 환경설정 – 팝업창 띄우기
[ EditText Preference ]
16장
17장
[ List Preference ]
18장
* 환경설정 – 팝업창 띄우기
16장
17장
18장
* 파일 – 고정된 파일, 읽고 쓰기
16장
17장
18장
Res/raw 폴더에 xml 파일 위치시킴(App와 같이 배포됨)
이 xml을 활용하기 위해
Resources객체를 통해야 한다.
getResources() 메소드를 호출
한다.
호출된 Resources 객체의
openRawResource() 메소드를
또 호출한다.
그러면 시스템이 내용을 읽는
InputStream을 생성해준다.
역시 시스템에 내장된 XML
파서(parser)를 통해 Document
객체로 변환한다.
변환된 Document 객체에서
Word 형식을 추려내어
ArrayList > ArrayAdapter 보냄
* 파일 – 고정된 파일, 읽고 쓰기
16장
17장
18장
* 파일 – 고정된 파일, 읽고 쓰기
16장
17장
18장
* 파일 – 고정된 파일, 읽고 쓰기
16장
17장
18장
Notes.txt를 res/raw로부터 불러옴
크게 Resume 와 Pause 상황이 있는데
기본적으로 Bundle Create 되었을 때
Resume 상태이므로 이곳에서
Try-catch를 이용해 InputStream 객체 생성
긴 문자열이 예상되므로
(XML에서 EditText 하위 엘리먼트에
Android:singleLine이 ‘false’ 이므로)
String Buffer를 준다.
→ StringBuffer buf=new StringBuffer();
[ p.254~256 ]
Pause 클래스에서는 OutputStreamWriter
인스턴스를 이용해 notest.txt에
변경된 내용을 저장한다. 물론,
Try-catch를 이용한 예외처리가 들어간다.
* 파일 – 고정된 파일, 읽고 쓰기
16장
17장
18장
* 리소스(Resources)
19장
20장
정의
• 자바 코드가 아닌 다른 파일에 고정적으로 보관된 내용
종류
• Res/anim : 애니메이션 인터페이스
(바로 다음슬라이드에서 설명)
• Res/drawable : 아이콘, 그림 등 이미지(주로 PNG)
• Res/values : 각종 환경(국제화, 지역화 관련 유용)
• Res/xml : 앱에서 필요로하는 데이터, 구조 등
21장
* 리소스 - 1. 문자열
19장
20장
21장
* 리소스 - 2. 이미지
01
02
03
04
05
06
07
08
09
10
11
<ImageButton
android:id="@+id/format"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:src=
"@drawable/icon"
/>
19장
20장
ImageButton
btn=(ImageButton)findVie
wById(R.id.format);
21장
01
02
03
04
05
06
07
08
09
10
11
* 리소스 - 3. XML
19장
20장
21장
XML 파일을 res/xml에 넣어둔다.
JAVA코드에서,
리소스 클래스 getXML() 메소드 R.xml
뒤에 해당 XML 리소스 ID를 넘겨주면
접근이 가능하다.
Androids.xml 을 넣어두었다면,
getResources().getXml(R.xml.androids)
로 호출하면 된다.
getXml() 메소드는 해당 패키지의
XmlPullParser 클래스를 리턴한다.
이것은 이벤트 방식으로 동작하는데
사용부분에서 계속적으로 next()를
호출해 다음 엘리먼트를 뽑아낸다.
* 리소스 - 4. 기 타
19장
20장
1. res/values 디렉토리에는 크기, 색깔, 배열 등의 단순한 값 역시
각자 xml 파일에 넣어두고 리소스로 사용이 가능하다.
2.
리소스로 사용되는 XML 파일의 최상위 엘리먼트는 항상 resources이고,
나머지 내용은 모두 resources 아래에 들어간다.
크 기(size)
• Dimen 엘리먼트를 사용하고, 실제 크기값은 본문 텍스트로 입력(px)
색깔(color)
• CSS(Cascading Style Sheet)와 유사하게 #RGB의 4가지 형식을 이용할 수 있다.
배열(array)
• <string-arry> 밑에 <item>의 각각 실제 본문 텍스트로 입력
21장
* 데이터베이스 기초 개념
19장
[ CRUD for data, table ]
*
*
*
*
Create : 생성
Read : 읽기
Update : 수정
Delete : 삭제
CREATE TABLE [name] (PRIMARY KEY …)
INSERT INTO [name] SELECT or VALUES [data]
ALTER TABLE 일부, UPDATE – SET
DROP TABLE or DELETE - WHERE
20장
21장
* 데이터베이스 다루기 – 3가지
19장
20장
1. 쿼리문(Query Sentence) 이용
질의의 결과는 Cursor로 변환
2. DB값을 가지는 객체 – 가져오기
Cursors
3. DB값을 가지는 객체 - 입력하기
Content Values
21장
* 1. 쿼리문 이용 - 기초적
19장
20장
* Public Cursor query
(String table, String[] columns, String selection, String[] selectionArgs,
String groupBy, String having, String orderBy, String limit)
- Table : 질의를 수행할 테이블 이름
- Columns :자료를 받아올 필드로, null을 입력하면 모든 필드를 반환
- Selection : SQL의 "where" 구문에 해당되는 조건을 입력
조건이 많을 경우, ?로 대체함
- SelectionArgs : Selection을 ?로 지정하였을 경우, 그 조건들을 입력
- GroupBy : SQL의 "group by"구문에 해당
- Having : groupBy를 지정했을 경우, 그 조건을 넣어줌
- OrderBy : 결과값 정렬 방식을 지정함, null을 입력하면 기본 정렬을 수행
- Limit :결과값의 개수를 제한
21장
* 2. DB객체 - 받아오기
[ 커서의 개념 – 레코드를 가리킴 ]
19장
01
02
03
04
05
06
07
08
09
10
11
20장
21장
String name = result.getString(1);
- 레코드로부터 이름 받아오기
Long phone = result.getLong(2);
- 레코드로부터 전화번호 받아오기
[ Cursour 인스턴스의 메소드 이용 ]
* 3. DB객체 - 입력하기
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
19장
[ 데이터 입력부분 ]
ContentValues newValues = new ContentValues();
newValues.put("name", "구글");
newValues.put("phone", "1234567");
[ 레코드의 추가 부분 ]
myDB.insert("data", null, newValues);
20장
21장
* 외부 자바 라이브러리
19장
20장
21장
* 주의사항 + 빈셸 구동순서
19장
20장
21장
* Code + Execution
19장
20장
// 예외처리 부분
Exception! 메시지 출력
OK 버튼, null 값 반환
21장
* 인터넷 연결 – 1. 기본 HTTP 작업
22장
23장
24장
// WebView 브라우저와
HttpClient는 별개의 개념으로 따로 선언한다.
// browser 객체를 생성, client라는 HTTP 요청
처리 기본 클라이언트 객체 생성
* 인터넷 연결 – 2. 결과 분석(파싱)
22장
// DOM 파서에서 본문의 내용을 InputStream 형태로 받아온 후 분석
// Document 객체에서 필요정보를 뽑아내 forecast에 값을 설정
23장
24장
* 인터넷 연결 – 3. 파싱 후 재구성
22장
23장
24장
// bufResult에 값을 append
(for문 이용 날씨 출력)
1. “ “ 사이에 <> HTML 코드
를 기술한다. <br>은 별도
2. 필요한 함수는 미리 정의
후에 메소드 형태로 CALL
// 리턴함 = 출력(toString)
* 인텐트 – 개념, 준비과정 (1/3)
23, 24, 25장
인텐트(Intent)란?
Launcher에 나타나지 않는 특별한 액티비티(MP3, RSS Feed ...)
를 실행할 방법이 있어야 한다. 안드로이드 시스템에게, 어떠한
작업을 요구하는 ‘메시지(Message)’ 이것이 인텐트이다.
일종의 독립적인 액티비티라고 볼 수 있다.
HTTP[대]
• Action (Back, Forward, Stop …)
Intent[응]
• Action (View, Edit, Pick …)
• URL (http://www.google.co.kr)
• Data (content:// …)
* 인텐트 – 개념, 준비과정 (2/3)
23, 24, 25장
* 인텐트 – 개념, 준비과정 (3/3)
01
02
03
04
05
06
07
08
09
10
11
<intent-filter>
<action android:name=
"android.intent.action.
MAIN" />
<category android:name=
"android.intent.category.
LAUNCHER" />
</intent-filter>
23, 24, 25장
<receiver android.name=
“.MyIntentReceiverClassName” />
01
02
03
04
05
06
07
08
09
10
11
* 인텐트 – 액티비티 실행하기
23, 24, 25장
public Intent(Context packageContext, Class)
* 인자1 : PackageContext : 호출한 액티비티
* 인자2 : Class : 호출할 액티비티(.class)
public void startActivity(Intent intent)
* 파라미터(인자)로 받은 intent 실행
* 인텐트 – 액티비티 실행하기 (1/2)
23, 24, 25장
// 위, 경도
[ 버튼이 클릭되었을 때, 입력된 위도(lat)와
경도값(lon) 연결 geo:로 시작하는 Uri 생성,
그것을 Intent에 넣어 startActivity한다
(ACTION_VIEW – 데이터) ]
* 인텐트 – 액티비티 실행하기 (2/2)
23, 24, 25장
// 탭 생성 getTabHost()
// 에이콘 탭 – AcornBro...class CALL
// 안드로이드 탭 – And..class CALL
탭마다 class 경로를 주어
해당하는 탭의 내용을 실행
(Intent → Activity)
loadUrl(“http주소”)로
웹브라우저 불러오기(WebView)
* 인텐트 – 액티비티 실행하기 (2/2)
23, 24, 25장
[ 해당하는 탭의 Intent가 탭(tab)별로 독립적으로 실행된다 ]
(스위칭 가능, 전화나 지도 가능)
* 화면 회전 처리
26장
(AVD 화면회전 Ctrl + F12)
[ 세로보기 ]
[ 가로보기 ]
화면 회전시, Android System은 기본적으로 액티비티를 새로 만든다.
따라서, 기존의 상태를 보관해야 한다. (실행 상태 Bundle 보관)
화면 회전 상태를
landscape mode 라고 한다.
* 화면 회전 처리 – RotationTwo
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(p. 348)
(1/2)
26장
public class RotationTwoDemo extends Activity {
static final int PICK_REQUEST=1337;
Button viewButton=null;
Uri contact=null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 인스턴스 상태 저장 메소드
setContentView(R.layout.main);
// main.xml로 기본 레이아웃 지정
Button btn=(Button)findViewById(R.id.pick);
// 첫 번째 버튼 생성 - pick(선택)
btn.setOnClickListener(new View.OnClickListener() { // 클릭 리스너
public void onClick(View view) {
Intent i=new Intent(Intent.ACTION_PICK,
// 인텐트를 생성한다. ACTION_PICK
Uri.parse("content://contacts/people"));
// 데이터(uri)는 people(주소록)
startActivityForResult(i, PICK_REQUEST); } });
viewButton=(Button)findViewById(R.id.view);
// 실행 후, 그 결과를 반환한다.
(=startActivityForResult)
// 두번째 버튼 생성 – view(보기)
viewButton.setOnClickListener(new View.OnClickListener() { // 클릭 리스너
public void onClick(View view) {
startActivity(new Intent(Intent.ACTION_VIEW, contact));
} });
restoreMe();
viewButton.setEnabled(contact!=null);
// 기본 Uri 타입 contact 변수
값은 null인데, 그것이 아니면 활성화 시켜라 = 버튼1에서 무언가 받아오면
* 화면 회전 처리 – RotationTwo
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
(p. 348)
(2/2)
26장
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode==PICK_REQUEST) {
// 액티비티 결과 정의 메소드
if (resultCode==RESULT_OK) {
// 액티비티 실행 결과로 PICK_REQUEST, OK를
contact=data.getData();
받으면 contact 변수에 데이터를 받아오고,
viewButton.setEnabled(true);
두 번째 버튼인 ‘보기’를 활성화 시켜 값 리턴
}
}
}
@Override
public Object onRetainNonConfigurationInstance() {
return(contact);
}
private void restoreMe() {
contact=null;
if (getLastNonConfigurationInstance()!=null) {
contact=(Uri)getLastNonConfigurationInstance();
}
}
}
// Uri 인스턴스를 문자열 변환하지 않고
그 자체로 보관한다.
(사실상 saveInstanceState를 대체한다)
// 기본적으로 null 값을 contact 변수에
할당하고 조건문에서는,
// 마지막으로 받아둔 Uri 인스턴스가 있다면
contact 변수에 인스턴스를 그대로 세팅한다.
* 화면 회전 처리 – RotationTwo 실행
[ 1. 실행시 초기화면.. 보기 버튼이 비활성화 되어있다.
2. 선택을 눌러 연락처를 선택했더니, 3. 보기 버튼이 활성화 된다 ]
26장
* 화면 회전 ‘직접’ 처리하기
26장
[ 다음과 같이 configChanges=“keyboardHidden → 물리적 키보드
orientation → 중력가속도 센서 변화 ]
※ 주의할 점 : 어플리케이션이 아닌 액티비티에 설정됨 / JAVA 소스 구성은 같음
onCreate() 대부분을
setupView()에서
onConfiguration
setupView()가 처리
레이아웃, 버튼 처리
Changed() 화면처리
* 화면 회전 고정 + 중력가속도계만 사용
1. 화면 회전 방지
Android:screenOrientation=“portrait” / “landscape”
▶ AndroidManifest.xml의 화면 회전 부분에 2가지 속성 중 하나 추가
※ 주의할 점 : 전 슬라이드에서 밝힌 바와 같이, 액티비티에 추가되는
속성이므로 해당 액티비티마다 모두 속성을 주어야 함
2. 강제로 G센서 이용
Android:screenOrientation=“sensor”
▶ AndroidManifest.xml의 화면 회전 부분에 ‘sensor’ 속성 추가
※ 활용 분야 : T1 모바일 같은 슬라이딩 키보드 채택 기기에서
G센서를 이용해 화면 회전을 해야 할 경우 사용됨
26장
* 컨텐트 프로바이더의 필요성
27~28장
[ 한 앱이 다른 앱의 DB에 직접 접근하는 것은 불가능하다 ]
[ 앱에 컨텐트 프로바이더를 설정 후 리졸버를 통해 접근한다 ]
* 컨텐트 프로바이더란?
27~28장
Content Provider (내용 공급자)
• Uri(데이터)의 인스턴스가 가리키는 Target(특정 데이터)을
제공할 수 있게 준비된 일종의 프로그램 (추상 인터페이스)
일반 파일
SQLite
인터넷
원격 서버
* 컨텐트 프로바이더 구성
Uri 값(DATA) 구성요소
27~28장
* 컨텐트 프로바이더 쿼리(Query)
쿼리 Uri 이름
가져올 Uri 속성의 배열
27~28장
추가적인 조건, 정렬 조건
[ 가져올 Uri 속성의 배열 – ‘PROJECTION’ ]
어떤 속성을 사용할 것인지 자세히 정의해 주어야 한다. (ID, TITLE, VALUE…)
* C·P를 통한 데이터 자동 적용 (1/2)
27~28장
// 이전 슬라이드에서 설명한
managedQuery 메소드 정의
// Cursor 인스턴스가 가진 내용을
ListView나 Spinner 같은 선택
위젯에 표현해주는 클래스 정의
■
■
■
■
this : ContantsBrowser 액티비티 스스로의 인스턴스 사용
R.layout.row : 목록 항목을 표시하는데 사용되는 레이아웃(row.xml)
constantsCursor : Cursor 인스턴스
TITLE, VALUE : 사용할 Uri의 속성 이름 배열 + title, value.xml
* C·P를 통한 데이터 자동 적용 (1/2)
27~28장
* 데이터의 추가와 삭제
27~28장
// values.put을 통해 TITLE, VALUE에 데이터를 추가한다.
// 컨텐트 프로바이더의 인스턴스를 받아오는 액티비티의 메소드
// 앞에 지정한 values. 값(title, value)을 불러온 컨텐트 프로바이더에 insert 한다.
■ insert() : 특정 데이터 Uri와 ContentValues(이미 값 가짐)로 ‘행 추가’
■ bulkInsert() : insert할 배열을 넘겨 ‘여러 행 한꺼번에 추가’
// 삭제 시에는 3가지의 인자가 필요하다.
순서대로, Uri / 조건문 / 조건값 : ? 부분 배열
* 컨텐트 프로바이더 구현 – 4단계 과정
1
2
3
4
• 클래스 생성 (6 메소드 이용)
• Uri 지정
• 속성 정의 (외부 액티비티를 위해)
• Manifest.xml 설정
27~28장
* 컨텐트 프로바이더 구현 – 1/4 단계
onCreate()
• 가장 먼저 실행
• 초기화 작업 담당
Update()
• 존재하는 데이터
값 변경
Query()
• 조건을 입력받아
결과를 뽑아줌
Delete()
• 데이터 개별항목,
집합 값 삭제
27~28장
Insert()
• 새로운 데이터
항목 생성, 입력
getType()
• Uri에 해당하는
MIME 타입 리턴
* 컨텐트 프로바이더 구현 – 1/4 단계
27~28장
1. onCreate()
[ 데이터베이스가 사용 가능한지 여부를 확인하는 DatabaseHelper() 클래스 ]
(자세한 설명은 데이터베이스 관련 장에서…)
* 컨텐트 프로바이더 구현 – 1/4 단계
27~28장
2. Query()
■
■
■
■
■
Uri 이름 : 쿼리를 실행할 대상 데이터 집합 / 개별 항목
projection : 속성 이름을 가리키는 문자열 배열(String [])
selection : SQL의 WHERE 조건문과 같음
selectionArgs : 3번째 인자 WHERE 조건문에 ? 인자 지정시 그 값
sort : SQL의 ORDER BY(정렬)과 같음
SQLiteQueryBuilder
인스턴스에
인스턴스의
인스턴스 생성
입력 항목 값 추가
Query() 실행해 출력
* 컨텐트 프로바이더 구현 – 1/4 단계
27~28장
3. Insert()
// constants : 바로 위에 put에서
계속 정의되고 있는 TITLE과 VALUE
// getNullColumnHack() : 이 java 맨
아래에서 정의된 클래스로 title을
값으로 리턴받음
// cv : 바로 앞에서 생성된 ContentValues
[ 전체 동작구조는 query와 동일 ]
* 컨텐트 프로바이더 구현 – 1/4 단계
27~28장
4. Update()
// isCollectionUri : 이것이 데이터 집합
Uri 인지 확인하는 부분
만약 그것이 맞다면, 작업을 그대로
진행한다. (간단히 1줄로 코딩됨)
// 개별 항목 Uri 라면, 해당하는
부분만 업데이트 하도록 조건을
하나 추가해 준다.
5. Delete()
* 컨텐트 프로바이더 구현 – 2~4/4 단계
27~28장
[2] Uri 지정
Public static final Uri CONTENT_URI=
Uri.parse(“content://com.comonsware.android.tourit.Provider/tours”);
// public static 상수값으로 데이터 유형별 Uri 제공
다른 것과 중복되지 않게 패키지 이름 구조 사용해도 무관함
[3] 속성 정의
Public static final class Constants implements BaseColumns {
public static final String DEFAULT_SORT_ORDER=“title”;
public static final String TITLE=“title”;
// public static final로 선언된 BaseColumns 상수 정의 후, 그 안에 속성을 정의
[4] 매니페스트 설정
<provider
android:name=“.Provider”
android:authorities=“com.comonsware.android.tourit.Provider” />
// .의 의미는 어플리케이션 기본 패키지 안에 들어있다는 것이다.
각 CONTENT_URI에 지정된 컴포넌트 ID를 모두 authorities에 기술 (;로 구분)
* 권 한 (Permissions) – 확보 (uses-permission)
29장
[ AndroidManifest.xml ]
<uses-permission
android:name=“android.permission.ACCESS_COARSE_LOCATION” />
▶ 안드로이드 내장 권한은 uses-permission으로 시작한다.
▶ 앱 확보 권한은 android.name 속성에서 정의한다.
▶ 자세한 권한 소개는 Android SDK – manifest.permission 참고
[ 자주 사용되는 권한 ]
■ INTERNET
자바 소켓부터 WebView까지 인터넷 관련 권한을 다룬다.
■ READ_CONTACTS
컨텐트 프로바이더 데이터 엑세스 권한
■ WRITE_CONTACTS
컨텐트 프로바이더 데이터 변경 권한
* 권 한 (Permissions) – 요청 (permission)
[ FOCUS ON ]
권한으로 보호하고자 하는 것은
외부 앱의 데이터 침범이 아니라,
휴대폰 소유주에 대한 사생활이다.
1. I D - 중복 방지를 위해 패키지 명 활용 권고
2. 제 목 - 권한을 요청할 때, 표시할 내용
3. 설명문 - 권한을 요청할 때, 짧은 설명 문장
<permission
1. android:name=“vnd.tlagency.sekrits.SEE_SEKRITS”
2. android:label=“@string/see sekrits label”
3. android:description=”@string/see sekrits description”
29장
30~31장
Service 클래스를
Activity와 연결하는
Method (Binding)
onCreate(생성) → onStart(시작) → onDestroy(종료)
* 서비스(Service)의 구현 - Lifecycle
// 안드로이드 시스템 기본 초기화
// 텍스트 형식으로 설정(format)
// ‘위치관리자’ 인스턴스를 받아오고, gps라는 위치제공자를 이용함
위치가 변경될 때마다 변경을 요청하고 받아오는 리스너 등록
// 안드로이드 시스템 내부 종료(Destroy 메소드)
// 위치관리자 서비스 사용 해제
30~31장
* 서비스(Service)의 구현 – IPC 정의 (1/2)
// Interface로 시작(자바와 같음)
■
■
■
■
기본 데이터 타입(int, float, double, boolean)
String, List, Map ( java.util 패키지)
Parcelable(안드로이드 직렬화 기법) 클래스
기타 AIDL로 정의된 데이터 타입
30~31장
* 서비스(Service)의 구현 – IPC 정의 (2/2)
// 서비스(Service) 인터페이스 내부의 메소드를 호출한다.
// 현재 위치에 가장 최근의 날씨를 리턴한다(forecast)
30~31장
* 서비스(Service)의 구현 – Manifest
30~31장
<uses-permission> 사이에 import된 관련 패키지들의 권한 설정을 해 준다.
<Application> 사이에 <Service> android:name= 인터페이스 정의를 해 준다.
* 서비스(Service)의 구현 – IPC 호출
30~31장
// url의 포맷 정의(String, format)
// URL을 가져오는 getMethod
// 응답핸들러를 생성하여 getMethod를 통해 응답내용
객체에 날씨에 대한 결과를 받아오고 generatePage 한다.
// Forecast 객체로 분석된 결과를 변환한다.
// 관심있는 인텐트(컴포넌트)에게 결과를 전달한다.
// 의무화된 try-catch 구문을 통해 예상치 못한 오류를 받아낸다.
* 서비스(Service)의 구현 – NWS
[ National Weather Service의 XML 페이지 ]
30~31장
* 서비스(Service)의 호출
30~31장
1. [바인딩]
• AIDL을 확보
(바인딩)
2. [호출]
• AIDL내부 메소드
3. [연결 해제]
• 인터페이스 해제
* 서비스(Service)의 호출 준비 (1/2)
30~31장
[ 서비스를 사용하려면 ServiceConnection 클래스를 상속받아야 한다 ]
// Ibinder : IPC를 호출하는 창구 역할
// ComponentName : 연결하려는
서비스를 가리킴 (컴포넌트 이름)
// IPC를 호출하는 창구인 아이바인더를 인자로 받아,
AIDL에 정의된 인터페이스로 형변환한다.
그러면, IPC를 실행해 updateForecast() 가능하다.
// 서비스 연결이 끊기면, 해당 서비스 변수값은 null 값을
주어 destroy의 의미를 가지게 해 준다.
bindService(serviceIntent, svcConn, BIND_AUTO_CREATE);
“ 액티비티 내부에서 Service를 쓰기 위해 “
1. Intent (호출하려는 Service를 정의하는 Intent)
2. ServiceConnection
3. 기타 옵션 설정 플래그
* 서비스(Service)의 호출, 해제 (2/2)
30~31장
호출하기
앞서 설명한 바인딩(Binding)과정을 통해,
서비스 인터페이스 객체가 서비스를 시작할 준비를 마쳤다면
액티비티 내부의 bindService()를 통해 서비스를 호출할 수 있다.
수동 실행시(=non IPC), startService(), stopService() 호출한다.
[예외처리]
1> DeadObjectException – 서비스 연결의 비정상 종료
2> RemoteException – 프로세스간 통신 문제(범용 예외처리)
해제하기
ServiceConnection
unbindService()
변수 = null 설정
* 사용자 알림 메시지 – 실행모습
[ 화면 최상단에 알림메시지 알림이 나타나고, 클릭할 경우 리스트가 출력된다(왼쪽)
해당 아이템을 클릭하면 리스트화 되어 내용 확인이 가능하다 ]
* 사용자 알림 메시지 예제 - 분석 (1/2)
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btn=(Button)findViewById(R.id.notify);
// 예외를 위해saveInstanceState 활용
// main.xml - 2개의 버튼으로 구성됨
// 알림메시지 전달 버튼 (Button 1)
btn.setOnClickListener(new View.OnClickListener() {
// 버튼 클릭 이벤트 리스너
public void onClick(View view) {
TimerTask task=new TimerTask() {
// 새로운 타이머 작업 생성
public void run() {
notifyMe(); // 실행되면, 알림메시지 호출
}
};
}});
timer.schedule(task, 5000);
btn=(Button)findViewById(R.id.cancel);
// 알림메시지 중단 버튼 (Button2)
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
NotificationManager mgr=
}});}
// 5초 후에 표시한다.
// 버튼 클릭 이벤트 리스너
(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
// 새로운 알림메시지관리자 생성(알림 서비스를 인자로 가진다)
mgr.cancel(NOTIFY_ME_ID);
// 알림 메시지 아이디를 받아와, 중단시킨다(mgr.cancel)
* 사용자 알림 메시지 예제 - 분석 (2/2)
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
private void notifyMe() {
// 핵심적인, 알림메시지 표시 기능 클래스
final NotificationManager mgr=
(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
// 역시, 알림메시지관리자를 생성해 알림 서비스를 인자로 받아온다. (인스턴스 확보 과정)
Notification note=new Notification(R.drawable.red_ball,
// note라는 이름의 알림 인스턴스를 생성하고, 아이콘은 red_ball로 설정한다.
"알림 메시지!",
// 알림 메시지를 알리는 부분
System.currentTimeMillis()); // 발생 시각은 현재 시간으로 준다.
PendingIntent i=PendingIntent.getActivity(this, 0,
// 인텐트를 생성해 실행할 알림메시지를 그 대상으로 준다.
new Intent(this, NotifyMessage.class), 0);
// NotifyMessage.class가 i라는 이름의 PendingIntent 대상이다.
note.setLatestEventInfo(this, "알림 제목", "알림 메시지 본문입니다.", i);
// 알림 메시지 창에서의 해당 이벤트 제목과 본문을 지정한다.
다
note.number=++count;
// 알림 메시지 노트의 번호를 증가시킨다.
mgr.notify(NOTIFY_ME_ID, note);
// 알림 메시지 관리자에 note를 통한 알림 인스턴스를 넘겨 표시한