2011년 5월 18일 수요일

가로모드 세로모드 확인 방법

if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)

{

// 세로 모드

}else if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)

// 가로 모드

}

안드로이드 노트 어플 GW NOTE (메모, 할일, 이벤트, 시간표)






GW Note는 할일(Todo), 메모 (Memo), 스케쥴(Schedule) 뿐 아니라
과목마다 과제, 메모등을 추가하여 관리할 수 있는 강력한 기능의 시간표를 작성 할 수 있습니다.

직관적인 화면 구성으로 쉬운 사용자 환경을 가지고 있
습니다.

- 시간표 기능 (TimeTable)
GW 시간표는 단순히 일주일 동안의 시간표 목록만 보여 주는 것이 아니
각 과목별 과제를 등록하고 관리 할 수 있도록 도와 줍니다.
과제 완료일을 설정 할 수 있을 뿐아니라 완료한 과제와 완료하지 못한 과제를 분리하여 관리 할 수 있습니다.
과제, 메모 추가는 단순히 메모 작성 뿐아니라 사진을 추가하여 작성 할 수 있어
시간표는 가로 보기 및 세로 보기 모드를 지원합니다.
가로 보기 모드에서는 전체적인 시간표를 확인 할 수 있고 세로 모드에서는 자세한 과목 정보를 확인 할 수 있습니다.

- 사진 첨부 기능
모든 노트 (메모, 할일, 이벤트) 에 사진을 추가할 수 있습니다.
단지 첨부기능이 아니라 마치 워드 프로세스와 같이 원하는 위치에 사진을 추가하여 사진과 내용을 원하는 위치에
위치시킬 수 있으며 내용과 내용사이에 사진을 추가할 수 있습니다.

- 달력 기능 지원
양력과 음력을 모두 지원하며 만든 노트들을 날짜별로 확인 할 수 있고 달력을 통해 스케쥴 관리를 할 수 있습니다.
월별 보기 및 주별 보기를 통해 스케쥴을 관리해 보세요
- 알람 기능
할일, 이벤트 노트를 만들어 정해신 기한에 알람을 설정하면 원하는 시간에 알람으로 알려 줍니다.

- 반복 기능
- 반복되는 할일 들에 대해서 반복을 설정하면 정해진 기간마다 반복되는 할일 노트를 만들 수 있습니다.

- 할일 메모 작성
간단한 메모 작성 뿐아니라 해야할 일들을 작성 할 수 있는 Todo 기능을 지원 합니다.
각 폴더별로 할일 리스트를 따로 관리할 수 있어 관련있는 할일 들만 모아 정리 할 수 있습니다.

- 다양한 배경화면 지원
다양한 노트 배경화면을 적용하여 자신만의 노트를 만들어 보세요

- 가로 입력 모드를 지원합니다.
세로 모드 입력 뿐 아니라 가로 모드 입력이 가능하여 메모 작성시
넓은 키보드를 사용하여 좀더 편하게 입력이 가능합니다.

- 다양한 위젯 지원
(1 x 1), (1 x 2), (2 x 2) 사이즈의 메모, 할일, 이벤트에 대한 위젯을 제공합니다.
원하는 크기의 위젯을 적요하여 자신만의 위젯을 구성할 수 있습니다.
또한 4가지의 시간표 위젯도 지원 합니다.
작성한 시간표를 위젯을 통해 관리해 보세요

- 노트 공유 기능
작성한 노트를 SMS, MMS, 트위터, 이메일, 에버노트(Evernote) 등으로 메모, 할일, 이벤트 노트를 전달 할 수 있습니다.

- 암호 설정 기능
중요한 메모, 할일, 이벤트들이 포함된 폴더에 암호를 설정하세요

- 한글, 영문 지원
GW 노트는 한글과 영문 두가지 언어를 지원 합니다.

0.99$에 메모, 할일, 이벤트 및 시간표 기능까지 가능한 다기능 노트 어플을 만나 보세요

새로운 기능들은 계속 추가됩니다.


SQLITE Manager 사용하기

요즘 저는 모바일쪽에 많은 관심을 갖고 있습니다.
그 이유는 다른 분들도 같은 생각이시겠지만, 향후 생활에 접목되어서 많은 확장성과 발전 가능성이 보이는 분야이기 때문이죠.
그렇다고 웹을 절대로 무시하는 것은 아닙니다.
현재 운영되어지는 모든 그림들이 웹베이스의 모바일 클라이언트쪽의 모습이기 때문입니다.

그러면 모바일을 개발할 때 개발하는 언어와 상관없이 공통되게 사용하는 것이 있는데 그것은 SQL 입니다.
그 중에서 모바일쪽에서는 SQLITE 를 사용을 하지요.

SQLITE는 콘솔을 통해서 사용을 할 수 있지만 더 쉽게 사용하고 접근할 수 있는 방법으로 FireFox에다가 ‘Sql Manager’를 Add On을 해서 사용하는 방법이 있습니다.

그래서 그 방법에 대해서 설명을 하고 간단하게 1개의 데이터를 입력해 볼까 합니다.

1. SQLite Manager 설치하기


[FireFox를 실행하고 Tools에서 Add-ons를 선택합니다.]


[Get Add-ons에서 sqlite manager를 검색해서 ‘Add to Firefox’을 누릅니다. 그러면 설치가 완료되고 FireFox를 다시 시작할것이냐고 질문을 하는데 바로 YES를 합니다.]


[그러면 아까는 보이지 않던 Tools 메뉴에 SQLite Manager라는 메뉴가 생긴것이 보입니다. 사용하기 위해서는 선택을 하고 실행을 하면 되겠죠?]

2. DataBase 생성하기


[SQLite Manager를 실행하고 Database 메뉴를 선택하면 직관적으로 보이는 ‘New Database’라는 메뉴가 보입니다. 선택을 하고 원하시는 이름의 Database를 생성하면 됩니다.]


[경로에 대해서 고민하시는 분들이 있을지도 모르기에 우측상단에 보시면 Directory를 선택하면 ‘Select Default Directory’ 라는 메뉴가 보이고 선택해서 저장되기 원하는 경로를 설정하시면 됩니다. 당연히 생성하기 전에 설정하셔야 한다는 것은 감을 잡으셨으리라 굳게 믿습니다!]

3. Table 생성하기


[테이블을 생성하는 방법도 역쉬나 Database 생성하는 것만큼 쉽습니다. Table 메뉴를 눌러보시면 ‘Create Table’ 라는 메뉴가 보이고 선택을 하시면 테이블 생성을 위한 컬럼을 입력하는 창이 뜹니다.]


[생성창에서 원하는 컬럼명과 DataType 및 Primary Key 등의 설정을 입력하시면 됩니다.]


[입력을 완료하면 생성된 쿼리가 맞는지에 대한 확인 창이 뜨고 맞으면 Yes를 선택하시면 됩니다.]

4. 데이타 입력하기


[테이블까지 생성을 하셨다면 왼쪽의 생성한 테이블을 선택하시고 오른쪽 탭에 있는 ‘Browse & Search’라는 탭을 선택해서 ‘Add’ 버튼을 누르면 다음과 같이 데이타를 입력하는 폼이 뜹니다. 입력하는 방법은 원하시는 데이타를 타입에 맞게 넣어서 ‘OK’ 버튼을 누르시면 되겠습니다.]


[입력을 완료하고 나면 다음과 같이 데이타가 입력되어 있는 모습을 보실 수 있습니다. 저는 테스트를 위해서 한개만 입력하였습니다.]

SQLite Manager를 활용해서 데이타베이스 생성 및 테이블 생성, 데이타 입력까지 설명을 해 드렸는데요.
데이타베이스를 모바일 장비에서 사용하는 방법에 대해서는 생성한 위치에 가셔서 생성된 데이타베이스를 가지고 모바일 장비에 넣으시면 바로 사용할 수가 있습니다.

Bitmap과 Drawable간의 변형

Bitmap To Drawable

Bitmap bitmap = new Bitmap(...)

Drawable drawable = new BitmapDrawable(bitmap);

안드로이드 (Android) Bitmap 구현, 관리 하기

모든 프로그램에서 이미지 관리의 기본은 비트맵이다. 안드로이드에서도 마찬가지로

이미지 관리와 표현을 위해서는 비트맵을 익히는게 가장 기본이다. 그 비트맵 관련

내용들을 소개한다.

안드로이드에서 비트맵 관련 클래스는 android.graphics.Bitmap 이다. 그래픽 관련

클래스들은 android.graphics 패키지에 있으며 여기에 포함된 것이다.

그리고 객체 Factory 관리를 위한 BitmapFactory 클래스가 있다. BitmapFactory

여러가지 이미지 포맷을 decode 해서 bitmap 으로 변환하는 함수들로 되어있는데

그 이름들은 decodeXXX 로 되어있어서 쉽게 원하는 기능의 함수를 찾을수 있을

것이다.

(1) BitmapFactory 에서 주로 사용하고 있는 함수와 옵션에 대한 설명


BitmapFactory.decodeByteArray() : Camera.PictureCallBack 으로부터 받은 Jpeg 사진

데이터를 가지고 Bitmap 으로 만들어 줄 때 많이 사용한다.

Camera.PictureCallback 에서 들어오는 데이터가 byte[] 배열로 들어오기 때문이다.

BitmapFactory.decodeFile() : 로컬에 존재하는 파일을 그대로 읽어올 때 쓴다. 파일경로를

파라미터로 넘겨주면 FileInputStream 을 만들어서 decodeStream 을 한다.

1Bitmap orgImage = BitmapFactory.decodeFile(“/sdcard/test.jpg”);

BitmapFactory.decodeResource() : Resource 폴더에 저장된 그림파일을 Bitmap 으로

만들어 리턴해준다

1Bitmap orgImage =
2 BitmapFactory.decodeResource(getResources(), R.drawable.test02);

BitmapFactory.decodeStream() : InputStream 으로부터 Bitmap 을 만들어 준다.

BitmapFactory.Options : BitmapFactory 가 사용하는 옵션클래스이다. Options 객체를 생성하고

설정하고자 하는 옵션을 넣은후 BitmapFactory 의 함수 실행시 파라미터로 넘기면된다.

inSampleSize : decode 시 얼마나 줄일지 설정하는 옵션인데 1보다 작을때는 1이 된다.

1보다 큰값일 때 1/N 만큼 이미지를 줄여서 decoding 하게 된다. 보통 2의 배수로 설정한다.

1BitmapFactory.Options options = new BitmapFactory.Options();
2options.inSampleSize = 4;
3Bitmap orgImage = BitmapFactory.decodeFile(“/sdcard/test.jpg”, options);

(2) Bitmap 과 BitmapFactory 을 사용한 여러가지 예제


BitmapFactory 로 이미지를 읽어온뒤 Bitmap.createScaledBitmap() 사용해서 크기를 재조정

할수 있다. 하지만 예를 들어 크기를 일정하게 2, 4 배등으로 줄일거면 굳이 createScaledBitmap

을 사용하지 않고 위에서 설명한 BitmapFactory.Options inSampleSize 를 사용하면 된다.

아래는 SD 카드에서 이미지를 불러와 Bitmap 을 원하는 크기 만큼 줄인 예제이다.

1Bitmap orgImage = BitmapFactory.decodeFile(“/sdcard/test.jpg”);
2Bitmap resize = Bitmap.createScaledBitmap(orgImage, 300, 400, true);

다음은 BitmapFactory.Options 사용해서 이미지를 4배로 줄인것인데 createScaledBitmap

사용해서 용량을 줄인 이미지에 다시 입력한 크기만큼 가로, 세로 크기를 줄인 것이 된다

1BitmapFactory.Options options = new BitmapFactory.Options();
2options.inSampleSize = 4;
3Bitmap orgImage = BitmapFactory.decodeFile(“/sdcard/test.jpg”, options);
4Bitmap resize = Bitmap.createScaledBitmap(orgImage, 300, 400, true);

google_protectAndRun("ads_core.google_render_ad", google_handleError, google_render_ad);

[OutOfMemoryError??]

보통 이미지 파일을 읽어서 Resizing을 해야 할 때가 있는데,
그럴때는 BitmapFactory로 읽어서 Bitmap.createScaledBitmap() 메소드를 사용하여 줄이면

간단하게 처리 할 수 있습니다.

그런데 BitmapFactory를 사용할 때 주의해야 할 점이 있습니다.
아래의 예를 한번 보시죠.

Bitmap src = BitmapFactory.decodeFile("/sdcard/image.jpg");
Bitmap resized = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, true);

이미지 파일로부터 Bitmap을 만든 다음에

다시 dstWidth, dstHeight 만큼 줄여서 resized 라는 Bitmap을 만들어 냈습니다.
보통이라면 저렇게 하는게 맞습니다.

읽어서, 줄인다.

그런데 만약 이미지 파일의 크기가 아주 크다면 어떻게 될까요?
지금 Dev Phone에서 카메라로 촬영하면
기본적으로 2048 x 1536 크기의 Jpeg 이미지가 촬영된 데이터로 넘어옵니다.
이것을 decode 하려면 3MB 정도의 메모리가 필요 할 텐데,

과연 어떤 모바일 디바이스에서 얼마나 처리 할 수 있을까요?

실제로 촬영된 Jpeg 이미지를 여러번 decoding 하다보면

아래와 같은 황당한 메세지를 발견 할 수 있습니다.

java.lang.OutOfMemoryError: bitmap size exceeds VM budget

네... OutOfMemory 입니다.
더 이상 무슨 말이 필요 하겠습니까...
메모리가 딸려서 처리를 제대로 못합니다.

이것이 실제로 decoding 후 메모리 해제가 제대로 되지 않아서 그런 것인지,
하더라도 어디서 Leak이 발생 하는지에 대한 정확한 원인은 알 수 없습니다.
이것은 엔지니어들이 해결해야 할 문제 겠죠...

하지만 메모리 에러를 피할 수 있는 방법이 있습니다.


[BitmapFactory.Options.inSampleSize]

BitmapFactory.decodeXXX 시리즈는 똑같은 메소드가 두 개씩 오버로딩 되어 있습니다.
같은 이름이지만 Signature가 다른 메소드의 차이점은
BitmapFactory.Options를 파라메터로 받느냐 안받느냐의 차이죠.

BitmapFactory.Options를 사용하게 되면 decode 할 때 여러가지 옵션을 줄 수 있습니다.


여러가지 많지만 저희가 지금 사용할 것은 inSampleSize 옵션 입니다.

inSampleSize 옵션은,
애초에 decode를 할 때 얼마만큼 줄여서 decoding을 할 지 정하는 옵션 입니다.

inSampleSize 옵션은 1보다 작은 값일때는 무조건 1로 세팅이 되며,
1보다 큰 값, N일때는 1/N 만큼 이미지를 줄여서 decoding 하게 됩니다.
즉 inSampleSize가 4라면 1/4 만큼 이미지를 줄여서 decoding 해서 Bitmap으로 만들게 되는 것이죠.

2의 지수만큼 비례할 때 가장 빠르다고 합니다.
2, 4, 8, 16... 정도 되겠죠?

그래서 만약 내가 줄이고자 하는 이미지가 1/4보다는 작고 1/8보다는 클 때,
inSampleSize 옵션에 4를 주어서 decoding 한 다음에,

Bitmap.createScaledBitmap() 메소드를 사용하여 한번 더 줄이면 됩니다.

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap src = BitmapFactory.decodeFile("/sdcard/image.jpg", options);
Bitmap resized = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, true);

당연한 이야기 이겠지만,
내가 원하고자 하는 사이즈가 딱 1/4 크기라면

Bitmap.createScaledBitmap() 메소드를 쓸 필요가 없지요.

inSampleSize 옵션을 잘 활용하면 메모리 부족 현상을 대략적으로 해소 할 수 있습니다.
참고로 제가 저 옵션을 사용한 뒤로는 메모리 에러를 본적이 한~번도 없답니다.


[Appendix]

inSampleSize 옵션을 사용하면

SkScaledBitmapSampler Object (Library Level) 를 생성 하게 되는데,
Object를 만들때 정해진 SampleSize 만큼 축소하여 width와 height를 정한 뒤에 만들게 됩니다.

그러니까 애초에 축소된 사이즈로 이미지를 decoding 하는 것이죠.

Result Receiver for InputMethodManager

On a phone with a physical keyboard:
- if keyboard is not hidden don't bring up the soft keyboard.
- if the keyboard is hidden, need to do the SHOW_FORCED option which
is handled in the ResultReceiver class.
- depending on how you exit, it may leave the keyboard up - not
desirable, so I might try to address this.

On a phone without a physical keyboard:
- SHOW_IMPLICIT seems to work nicely and the keyboard doesn't stay up
when you exit the application.

View.OnLongClickListener mLongClickListener = new
View.OnLongClickListener() {

@Override
public boolean onLongClick(View v) {

softKeyboardResults rr = new softKeyboardResults();

Configuration config = MyView.this.getResources().getConfiguration
();
if (config.hardKeyboardHidden ==
Configuration.HARDKEYBOARDHIDDEN_YES) {
InputMethodManager imm = (InputMethodManager)
MyView.this.mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(MyView.this, InputMethodManager.SHOW_IMPLICIT,
rr);
}
return false;
}

};

class softKeyboardResults extends ResultReceiver {

public softKeyboardResults() {
super(getHandler());
}

@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);

switch (resultCode) {
case InputMethodManager.RESULT_HIDDEN:
case InputMethodManager.RESULT_SHOWN:
case InputMethodManager.RESULT_UNCHANGED_SHOWN:
break;
case InputMethodManager.RESULT_UNCHANGED_HIDDEN:
InputMethodManager imm = (InputMethodManager)
MyView.this.mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(MyView.this, InputMethodManager.SHOW_FORCED);
break;
default:
break;
}
}

}


InputMethodManager 와 textView/edittextview 를 통한 소프트키보드 제어하는법

1. 가상 키보드 사자리게하기

textView 와 edittextview 의 속성에 보면 .setInputType(0) 을 해주면 가상키보드가 더이상 뜨지 않는다 .

2. 키보드 선택

InputMethodManager IMM = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

IMM.showInputMethodPicker();

를 해주면 키보드 선택화면이 뜬다 .

3. 입력 선택

textView 와 edittextview 의 속성에 보면 setInputType(InputType.TYPE_CLASS_NUMBER); 를 하면 숫자 입력만 가능해진다 .

소프트 키보드가 업되어있다면 더이상 숫자 이외의 입력을 받아들이지 않는다 InputType 을 변경해서 입맛대로 조정 가능

4. 키보드 띄우기

InputMethodManager IMM = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

IMM.showSoftInput( view , IMM.SHOW_IMPLICIT);

지정된 소프트 키보드가 업된다 .

5. 키보드 사라지게 하기

InputMethodManager IMM = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

IMM.hideSoftInputFromWindow( ET_BARCODE.getWindowToken() , 0);

이것은 화면에 떠있는 키보드를 내려주기만한다

완전히 사용안할려면 해당뷰에 setInputType(0) 해주세요

Parcelable Object 만들기 (1)

Android의 핵심 중에서 Binder Driver라는 녀석이 있습니다.
Linux Kernel의 driver로 되어 있고, IPC이긴 하지만 기존의 IPC와는 살짝 다른 녀석 입니다.

저도 어떻게 만들었는지는 잘 모릅니다만,
shared memory를 통하여 오버헤드도 적고 프로세스 사이에 비동기로 호출도 이루어 진다고 합니다.
그리고 Binder는 기존 IPC처럼 데이터만 전달 하는게 아니라,
하나의 프로세스에서 다른 프로세스로 Object를 넘길 수도 있게끔 설계 되어 있습니다.
(물론 Serialize 기술을 사용하면 Object도 주고 받을 순 있지요.)

Binder를 통해서 넘기는 메세지 (data 와 object references) 는
Parcel 클래스에 저장이 되어서 넘어가게 됩니다. Parcel은 메세지 컨테이너인 셈이죠.

Parcel is not a general-purpose serialization mechanism. This class (and the corresponding Parcelable API for placing arbitrary objects into a Parcel) is designed as a high-performance IPC transport.

Parcel 클래스는 고성능 IPC 전송을 가능하게 끔 설계가 되어 있기 때문에,

모든 객체에 대해서 평범하게 serialization하지 않습니다.
그래서 모든 Object들을 Binder를 통해 주고 받을 수는 없습니다.


[Parcelable Interface]

Primitive Type과 Primitive Array Type은 기본적으로 parcelable 합니다.

뭐 그냥 일반 데이터인거죠.
그리고 Parcelable Interface를 implements한 클래스가 (당연히) parcelable 합니다.

오늘 우리가 할 일이 바로 이 Parcelable Interface를 사용하여
parcelable Object를 만드는 일 인 것이죠.

사실 parcelable한 type들이 많이 있습니다만, 나머지는 잘 모르겠군요... 어렵습니다.
여튼 오늘은 parcelable Object를 만드는 것만 생각 합시다.


[Parcelable Rect]

Rect 클래스야 다들 쉽게 만드실 겁니다.
left, top, right, bottom 4개의 필드만 있으면 되죠.


integer든 float이든 상관 없습니다만....
Android에는 Rect 클래스의 float 버전이 RectF 클래스 라고 따로 되어 있기 때문에,

저는 integer로 만들겁니다.


public class Rect {
public int left;
public int top;
public int right;
public int bottom;
}


뭐 아주 간단 합니다. 그냥 C에서의 구조체 수준이네요.
이것을 parcelable하게 바꾸어 봅시다.

Step 1.


public class Rect implements Parcelable {
public int left;
public int top;
public int right;
public int bottom;

public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(left);
dest.writeInt(top);
dest.writeInt(right);
dest.writeInt(bottom);
}
}


Parcelable을 implements하게 되면 꼭 추가해야 한다는 메소드 두 개도 같이 넣었습니다.
내용도 채워 봤어요.

describeContents() 메소드는 일단 건너뛰고...
writeToParcel() 메소드는 Parcel에 데이터를 쓰는 부분 입니다.
그냥 무작정 쓰면 됩니다. 전 아무 생각 없이 순서대로 그냥 썼습니다.

그럼 이제 에러도 없으니 parcelable한 Rect 클래스가 되었느냐... 라고 한다면 아직 아닙니다.
쓰는건 있는데 읽는건 없네요...

Parcel로 부터 값을 읽어 오기 위해서는 Parcelable.Creator Interface 가 필요합니다.


[Parcelable.Creator Interface]

Parcel 에서 Parcelable 클래스의 인스턴스를 만들 때
CREATOR라는 static field를 찾아서 실행 합니다.
CREATOR는 Parcelable.Creator type 으로 만들어져야 하는데
이건 선언과 동시에 반드시 initialize 되어야 합니다.

클래스 따로 만들어서 initialize 하기도 쉽지 않습니다.
그냥 익명 클래스로 만들어 버립시다.

Step 2.


public class Rect implements Parcelable {
public int left;
public int top;
public int right;
public int bottom;

public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(left);
dest.writeInt(top);
dest.writeInt(right);
dest.writeInt(bottom);
}

public static final Parcelable.Creator CREATOR = new Creator() {
public Rect createFromParcel(Parcel source) {
Rect r = new Rect();
r.left = source.readInt();
r.top = source.readInt();
r.right = source.readInt();
r.bottom = source.readInt();
return r;
}
public Rect[] newArray(int size) {
return new Rect[size];
}
};
}


Parcelable.Creator 클래스는 createFromParcel() 과 newArray() 메소스가 필요 합니다.

newArray() 메소드도 일단 넘어가고...
createFromParcel() 메소드를 보면 리턴이 Rect입니다.
그래서 Parcel에서 값을 읽어 새로운 Rect 인스턴스를 리턴 하는 구조로 만들면 끝입니다.

readInt()를 했는데, 이것은 writeToParcel() 메소드에서 썼던 순서대로 읽어 오는 것입니다.
쓸 때는 무작정 썼지만 읽을 때는 조심스럽게 읽어야하죠.

이제 비로소 parcelable Rect 클래스를 만들었습니다.
그냥 별거 없군요...


[Appendix]

위에서 describeContents() 메소드와 newArray() 메소드는 그냥 넘어 갔었습니다.
네... 뭐 사실 잘 모르기도 합니다만,
그냥 보통 parcelable Object를 만드는데에 크게 중요한 부분은 아니지요. 아하하...

describeContents() 에서는 어떤 특별한 객체를 포함하고 있는지에 대한 설명을
리턴값으로 표현 하는 것이라고 보면 됩니다.
bit mask 형식의 integer를 리턴 하며,
값을 체크 할 때 bit mask 체크를 해서 어떤 것들이 들어 있는지 알 수 있습니다.

현재 사용하는 플래그는 Parcelable.CONTENTS_FILE_DESCRIPTOR (0x00000001)
하나 밖에 정의 되어 있지 않습니다.
소스를 다 뒤져 보지 않아서 또 어떤 값들이 쓰이는지는 확인 해보지 못했네요...

newArray() 메소드는 그냥 배열로 만들어서 리턴 하는 겁니다.
Parcel.createTypedArray() 메소드에서 newArray() 메소드를 호출 하는 걸 확인 했습니다.
나중에 createTypedArray() 메소드를 사용 할 일이 있다면 newArray()가 호출이 되는 것이지요.