2017년 6월 19일 월요일

[Android] Cursor 전체를 탐색하는 가장 안정적인 코드

여러가지 방법이 있지만, 제가 가장 바람직하다고 생각하는 방법입니다.

if (cursor != null) {
    if (cursor.moveToFirst()) {
        do {
            // access cursor items
        } while (cursor.moveToNext());
    }

    cursor.close();
}


moveToFirst() : Cursor를 가장 처음 item을 가리키도록 조작하고, item이 하나도 없다면 false를 return함. (정상동작시 true)

moveToNext() : Cursor를 현재 item의 다음 item을 가리키도록 조작하고, 이미 가장 마지막 item이라면 false를 return함. (정상동작시 true)

※ 주의 : cursor != null 과 moveToFirst()를 한번에 확인하면 Cursor를 close()할 조것을 놓치게 됨.

[Android] 어디서나 Context 가져오기


Android 프로그래밍을 하다보면 Context를 요구하는 API들을 많이 접하게 됩니다.

원칙적으로는 현재 루틴을 수행하는 owner component의 Context를 사용하는 것이 좋으나

다음과 같이 Application class를 사용하여 간단히 global Context를 어디에서나 사용할 수 있는 방법도 있습니다.

Android platform에서 singleton을 보장해주는 Application class를 이용하면 됩니다.

1. ApplicationClass.java 작성

// ApplicationClass.java

import android.app.Application;
import android.content.Context;

public class ApplicationClass extends Application {
    private static Context mContext;

    public ApplicationClass() {
        super();

        mContext = this;
    }

    public static Context getContext() {
        return mContext;
    }
}


2. AndroidManifest.xml에 등록


<Appilcation... android:name=".ApplicationClass" ... />



    
        
            
                
                
            
        
    


3. 사용법


Applicatoin 어디에서나...
    // 사용법

    Context globalContext = ApplicationClass.getContext();


2017년 6월 17일 토요일

[프로그래밍] Java JDK Byte.parseByte() API 버그


JDK는 Java Delvelopment Kit입니다.
JDK에서 제공하는 API라면 충분히 안정화 또는 검증이 되었을 것이라고 예상하시겠지만, 엄연히 bug가 존재합니다.

이번 글에서는 제가 개발 중에 마주쳤던 Byte.parseByte()의 문제점을 이야기해보려고 합니다.

Byte.parseByte()는 String으로 저장되어 있는 byte값을 byte자료형으로 변환해 주는 API입니다.
또한 추가 argument에 진법 정보를 추가로 전달하여 다른 진법으로 표현되어 있는 String 또한 byte 자료형으로 변환해 줍니다.





하지만 다른 진법으로 표현되어 있는 String을 변환할 경우, 정상적인 변환이 되지 않을 수 있습니다.
이해할 수 없는 NumberFormatException을 발생 시킵니다.

왜 그런지, JDK 8의 source code를 열어 확인해 보겠습니다.





내부적으로는 Integer.parseInt()를 사용합니다. 왜 parseByte()를 직접 구현하지 않았을까요?
이로 인해 문제가 발생합니다.

직접적인 예를 들겠습니다.
다음과 같이 파싱을 시도하면 NumberFormatException을 발생하게 됩니다.




이것은 엄연한 버그입니다. byte으로 '-128'로 표현되는 "80"(0x80) String을 파싱하지 못하고 있습니다.
source code상으로는 0x80~0xFF(-127~-1)범위를 제대로 파싱하지 못할 것입니다.

이 문제점을 모르고, 실전 code에서 parseByte()를 사용했다면, 예상치 못한 exception을 만나게 될 겁니다.
(JDK에 bug가 있을리 없을 거라고 생각하고, 이해할 수 없는 exception에 자신의 실력을 자책하는 개발자가 있을지도 모르겠네요.)

어찌 되었든 문제점은 알았고, parseByte()는 이제 사용하지 않는 게 좋겠습니다.
아마도 하고자 하는 바는 다음과 작성하면 해결할 수 있을 겁니다.