w.h.i.t.e notebook

Personal space with IT, Gadgets

Rest in Peace, Steve Jobs

20111006-093513.jpg

The Hero

스티브 잡스가 사망했다고 애플에서 밝혔네요.

애플 이사회에서 내놓은 성명 전문입니다.

We are deeply saddened to announce that Steve Jobs passed away today.

Steve’s brilliance, passion and energy were the source of countless innovations that enrich and improve all of our lives. The world is immeasurably better because of Steve.

His greatest love was for his wife, Laurene, and his family. Our hearts go out to them and to all who were touched by his extraordinary gifts.

고인의 명복을 빕니다.

DB error while creating CookieSyncManager

If the app has services, or other processes, then you can see this kind of error when using CookieSyncManager.

01-13 16:44:46.674: E/Database(4298): CREATE TABLE android_metadata failed
01-13 16:44:46.690: E/Database(4298): Failed to setLocale() when constructing, closing the database
01-13 16:44:46.690: E/Database(4298): android.database.sqlite.SQLiteException: database is locked
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method)
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:2113)
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.(SQLiteDatabase.java:1966)
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:887)
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:965)
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:958)
01-13 16:44:46.690: E/Database(4298): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:576)
01-13 16:44:46.690: E/Database(4298): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
01-13 16:44:46.690: E/Database(4298): at android.webkit.WebViewDatabase.getInstance(WebViewDatabase.java:214)
01-13 16:44:46.690: E/Database(4298): at android.webkit.WebSyncManager.(WebSyncManager.java:65)
01-13 16:44:46.690: E/Database(4298): at android.webkit.CookieSyncManager.(CookieSyncManager.java:69)
01-13 16:44:46.690: E/Database(4298): at android.webkit.CookieSyncManager.createInstance(CookieSyncManager.java:96)

This happens because the DB created inside the CookieSyncManager is accessible from only one process.
I couldn’t find the way to use the CookieSyncManager from more than one process.

Also, I tried to CookieSyncManager.createInstance() from one process and CookieSyncManager.getInstance() from another, but it didn’t work.

I should have to solve this problem by only using the CookieSyncManager from one process.
Also keep in mind that CookieManager requires CookieSyncManager to work.

여러 process에서 CookieSyncManager를 사용할 경우 DB error

Application에서 CookieSyncManager, CookieManager를 생성하게끔 되어 있었는데 Service, IntentService 등을 사용하게 되면서 아래와 같은 에러가 자주 발생하였습니다.

01-13 16:44:46.674: E/Database(4298): CREATE TABLE android_metadata failed
01-13 16:44:46.690: E/Database(4298): Failed to setLocale() when constructing, closing the database
01-13 16:44:46.690: E/Database(4298): android.database.sqlite.SQLiteException: database is locked
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method)
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:2113)
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.(SQLiteDatabase.java:1966)
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:887)
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:965)
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:958)
01-13 16:44:46.690: E/Database(4298): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:576)
01-13 16:44:46.690: E/Database(4298): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
01-13 16:44:46.690: E/Database(4298): at android.webkit.WebViewDatabase.getInstance(WebViewDatabase.java:214)
01-13 16:44:46.690: E/Database(4298): at android.webkit.WebSyncManager.(WebSyncManager.java:65)
01-13 16:44:46.690: E/Database(4298): at android.webkit.CookieSyncManager.(CookieSyncManager.java:69)
01-13 16:44:46.690: E/Database(4298): at android.webkit.CookieSyncManager.createInstance(CookieSyncManager.java:96)

이런 에러가 발생한 이유는 여러개의 process에서 CookieSyncManager.createInstance()를 하면서 내부의 DB를 create하는데 이 DB는 multi-process를 지원하지 않기 때문으로 보입니다.

여러 프로세스에서 CookieSyncManager를 사용할 수 있는 방법은 찾지못하였고 메인 앱에서만 CookieSyncManager를 사용하는 식으로 해결하였습니다.

테스트해본 결과 한 프로세스에서 createInstance()를 한 후에 다른 프로세스에서는 getInstance()로 가져올 수는 없었습니다.
그리고 참고로 CookieSyncManager를 생성하지 못하면 CookieManager도 사용할 수 없습니다.

XCode 4에서 NSZombieEnabled, NSDebugEnabled 설정 사용하기

NSZombieEnabled는 메모리를 해제하는 대신 NSZombie로 둠으로써 EXC_BAD_ACCESS같은 문제를 해결할 때 도움을 줍니다.

XCode 3에서는 Executables에서 프로젝트의 executable에 오른쪽 버튼으로 Get Info를 해서 Arguments의 Variables to be set in the environment에 NSZombieEnabled라는 variable을 추가하고 값을 YES로 해주면 활성화가 됩니다. (참조)

XCode 4에서는 Products에서 오른쪽 클릭을 해봐도 Get Info가 없는 것을 알 수 있습니다.
위에 메뉴를 보면 Product가 있는데 여기서 Edit Scheme에 들어가도록 합시다.

이제 여기서 Arguments에서 Environment Variables에 NSZombieEnabled, NSDebugEnabled와 같은 속성을 추가하면 됩니다.

또 다른 방법은 Diagnostics에서 옵션을 활성화해 줄 수도 있습니다.

다른 옵션들은 잘 모르겠는데 디버깅에 도움이 되는 옵션들로 보여집니다.

아이폰, 아이패드로 4명이 HDTV에서 레이싱 게임을 즐기자!

iOS용 레이싱 게임 Real Racing 2의 개발사 Firemint에서 iOS 5 대응 업데이트의 신 기능을 발표 했는데
무려 AirPlay를 이용해서 HDTV로 4명이 ‘파티 플레이’를 즐길 수 있는 모드입니다.

AirPlay는 작년 9월에 발표한 iOS 모바일 장치에서 애플 TV로 영상, 음악 미디어 등을 무선으로 전송하여 재생하는 기술입니다. (참고로 애플TV는 셋탑박스로써 일반 TV에 연결하여 사용합니다)

이 파티 플레이 모드를 즐길려면 최소 한 대는 A5 프로세서를 장착하고 있어야하며 (즉 아이패드2나 아이폰4S여야 하죠)
나머지 장치들도 iOS5가 설치되어 있어야 한다고 합니다.

현재도 Real Racing 2 HD는 AirPlay로 콘솔처럼 HDTV에서 무선 대화면 게이밍을 즐길 수 있습니다. 애플TV에서 720p의 고해상도로 플레이가 가능하며 Real Racing 2는 뛰어난 그래픽을 자랑하는 게임이죠.

이런 AirPlay를 이용한 멀티플레이어용 게임이 등장을 하게 되면 가장 타격을 입을 곳은 닌텐도로 보여지네요.
닌텐도가 강세를 보이는 분야가 주로 많은 사람들이 함께 즐길 수 있는 캐주얼한 마리오 카트나 스포츠류 게임들인데 이제는 각자 가지고 있는 iOS 장치로도 게임이 가능해질테니까요. (물론 애플TV도 있어야하는데 애플TV는 $99로 매우 저렴한 편입니다)

더군다나 PS3에서도 보기 힘든 720p의 고해상도에 자이로스코프를 이용한 모션인식멀티터치 인식도 뛰어나다는 장점이 있습니다.

닌텐도에서 발표한 차세대 콘솔 Wii U는 터치화면이 있는 컨트롤러가 특징인데 직격탄을 맞았다고 볼 수 있습니다. 더군다나 Wii U는 현재까지는 터치화면 컨트롤러는 1대까지만 지원하는 것으로 밝혀져 있습니다.

아이폰으로 인해 닌텐도DS의 매출에도 영향을 받는 중인데 닌텐도로써는 고심이 커질 것 같네요.

iOS 장치의 단점이라면 버튼이 없어 하드코어 게이밍에는 부적합한 면이 있다는 것인데 그 분야는 Xbox와 PlayStation라는 쟁쟁한 경쟁자들이 있지요. 그나마 마리오 같은 독점 컨텐츠가 있다는게 경쟁력인데 애플 앱스토어에서도 앵그리버드 등 많은 스타 게임들이 등장하고 있는 추세입니다.

3D로 승부수를 건 3DS와 터치스크린으로 승부수를 건 Wii U 모두 미래가 불투명해보여 안타까운데 일본의 애플로 불리는 닌텐도이니 만큼 또다른 혁신으로 헤쳐나갈 것이라 기대해봅니다.

본론으로 돌아가면 파티 플레이 기능을 포함한 Read Racing 2 메이저 업데이트는 iOS 5의 출시일인 10월 12일 같이 출시할 예정이며 현재 iPhone 버전(iTunes)은 $4.99 iPad 버전(iTunes)은 $6.99에 판매중입니다.

개인적으로는 그래픽도 한층 개선이 된다고 하니 무척 기대가 됩니다.
예전에 세일할때 샀던 게임이지만 이렇게 기대치 않게 메이저 업데이트를 해주고 아이폰, 아이패드를 가정용 콘솔로 만들어준다는게 참 매력적인 것 같습니다.
스티브 잡스가 나서서 만든 변화도 아니고 애플이 만든 생태계 속에서 이렇게 변화를 만들어간다는 것도 인상적입니다.

[관련기사]
Real Racing 2 first iOS game with 4-person split big screen action via AirPlay
Real Racing 2 shows off iPhone 4S’ graphical chops, brings split screen gaming to iOS (video)
4 iPhones + 1 Apple TV = Awesome Split-Screen Multiplayer Gaming

EditText에서 키 이벤트 처리

EditText에서는 OnKeyListener로 back키나 Enter키 입력은 받을 수 있는데
문자열같은 일반적인 키입력은 이벤트로 넘어오지 않습니다.

이런 이벤트를 받으려면 TextWatcher라는 것을 써야하더군요.

간단히 TextWatcher를 구현해서 EditText에 addTextChangedListener()를 해주면 됩니다.

TextWatcher textWatcher = new TextWatcher() {

	@Override
	public void beforeTextChanged(CharSequence s, int start, int count, int after) {
		// 텍스트가 변경되기전 입력한 내용에 대해
		// s는 변경할 수 없음
	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {
		// 텍스트를 변경된 후 변경 사항과 함께
		// s는 변경할 수 없음
	}

	@Override
	public void afterTextChanged(Editable s) {
		 // 텍스트가 변경된 후. 변경 사항은 알 수 없음
		// s는 변경 가능. 하지만 위 함수들이 다시 콜백됨을 유의
	}

};

editText.addTextChangedListener(textWatcher); // EditText인 editText에 textWatcher를 핸들러로 등록

Kernel.org 부활

8월 말쯤 닫혔으니 한달 이상 닫혀있던 kernel.org가 드디어 부활했다고 하네요.

해킹을 당한 이후에 구조를 변경했다고 하는데

너무 오래 걸린 것 아닌가 싶네요..

Kernel.org

Welcome Back Kernel.org

iOS 시뮬레이터에서 위치 이용

안드로이드 에뮬레이터는 말그대로 arm칩을 에뮬레이팅한 가상장치라 그지같은 속도로 욕을 많이 먹지만(잘 쓰지도 않음)
아이폰 시뮬레이터는 위치를 시뮬레이팅 해줄수가 없는 문제가 있다.
(update : Xcode 4.2의 시뮬레이터부터는 위치 시뮬레이팅을 지원한다)
이를 해결하기 위해서 시뮬레이터일 경우 코드상에서 특정 위치를 전송해주는 방법이다.

#if TARGET_IPHONE_SIMULATOR 

@interface CLLocationManager (Simulator)
@end

@implementation CLLocationManager (Simulator)

-(void)startUpdatingLocation {
    CLLocation *simulLoc = [[[CLLocation alloc] initWithLatitude:37.381 longitude:127.134] autorelease]; // 경도, 위도를 넣어주면 됨
    [self.delegate locationManager:self
               didUpdateToLocation:simulLoc
                      fromLocation:simulLoc];
}

@end

#endif // TARGET_IPHONE_SIMULATOR

URL의 최대 길이는?

따로 HTTP 프로토콜 스펙에 정의되어 있지는 않으며
웹브라우져와 서버의 제한이 다르다.

<웹브라우저>

Microsoft Internet Explorer

2083자까지 가능하다.

Firefox

Firefox 1.5.x에서 65,536자까지 출력이 가능했으며 그 이상도 동작. 글 작성한 분이 10만자까지 테스트했다고 한다.

Safari

80,000자까지 테스트했을 때 동작하였다고 한다.

Opera

190,000자까지 테스트했을 때 동작하였다고 한다.

 

<웹서버>

Apache

4000자 정도에서 “413 Entity Too Large” 에러가 발생

Microsoft IIS

기본 제한은 16,384자이며 수정가능하다.

Perl HTTP::Daemon (Server)

8000자까지 동작

http://www.boutell.com/newfaq/misc/urllength.html

소스코드에서 안드로이드 버전 확인하기

http://developer.android.com/reference/android/os/Build.VERSION.html

android.os.Build.VERSION.SDK_INT 가 SDK 버전을 뜻하는데
Build.VERSION_CODES의 상수들과 비교가 가능하다.

예) OS가 프로요 이전일때

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) {
	...
}