SharedPreferences 사용시 주의점

android 2013. 5. 24. 20:46

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

1. 가장 흔하게 실수하는 case

SharedPreferences preference = context.getSharedPreferences(PREFERENCE_FILE_NAME, Context.MODE_PRIVATE);

preference.edit().putBoolean(“testKey”, 10);

preference.edit().commit();

 

edit()를 각각 호출함으로써  editor A 에 값을 설정하고, editor B 를 커밋한 경우입니다. Edit() 설명을 보면 아래와 같습니다.

/**

     * Create a new Editor for these preferences, through which you can make

     * modifications to the data in the preferences and atomically commit those

     * changes back to the SharedPreferences object.

     *

     * <p>Note that you <em>must</em> call {@link Editor#commit} to have any

     * changes you perform in the Editor actually show up in the

     * SharedPreferences.

     *

     * @return Returns a new instance of the {@link Editor} interface, allowing

     * you to modify the values in this SharedPreferences object.

     */

    Editor edit();

리턴부분을 보면 new instance 라고 되어 있습니다. 즉 항상 새로운 editor instance를 반환하도록 되어 있습니다.  

 

2. Multi-process 환경에서

 

SharedPreferences를 이용하여 주로 설정값을 저장하는 용도로 사용하고 있습니다. 그런데 저장한 값이 읽어지지 않는 경우가 있었습니다. 더 정확하게는 예전의 값이 그대로 유지되는 경우입니다 

경험한 환경은 아래와 같습니다.

 

ProcessA에서 int 10을 씁니다 

SharedPreferences preference = context.getSharedPreferences(PREFERENCE_FILE_NAME, Context.MODE_PRIVATE);

Editor editor = preference.edit();

editor.putBoolean(“testKey”, 10);

editor.commit();

 

ProcessB에서 값을 읽습니다 ( 값이 않읽어진다. )

SharedPreferences preference = context.getSharedPreferences(PREFERENCE_FILE_NAME, Context.MODE_PRIVATE);

int localeIdx = preference.getInt(“testKey”, -1);

 

아래의 API 문서에서도 나와 있듯이 SharedPreferences는 process 사이에서 communication하기 좋은 방법입니다. 그런데 안된다 ㅠㅠ

API 문서를 찾아보니 아래와 같습니다 

public static final int MODE_MULTI_PROCESS

Added in API level 11

SharedPreference loading flag: when set, the file on disk will be checked for modification even if the shared preferences instance is already loaded in this process. This behavior is sometimes desired in cases where the application has multiple processes, all writing to the same SharedPreferences file. Generally there are better forms of communication between processes, though.

This was the legacy (but undocumented) behavior in and before Gingerbread (Android 2.3) and this flag is implied when targetting such releases. For applications targetting SDK versions greater than Android 2.3, this flag must be explicitly set if desired.

 

간단히 볼드부분을 번역하면 아래와 같습니다.

Gingerbread (Android2.3) 까지는 기본으로 MODE_MULTI_PROCESS가 설정되어 있었다.

Target SDK 버전이 Gingerbread (Android2.3) 보다 높으면 명시적으로 설정해야 된다.

( API level이 11 이므로 3.0 부터 사용하능하다는 이야기니까, 2.3 까지는 않써도 된다고 생각함. 그러나 버전 상관없이 다 동작하려면 항상 써주는게 좋다. )

결론은 아래처럼 변경하면 됩니다.

 

SharedPreferences preference = context.getSharedPreferences(PREFERENCE_FILE_NAME, Context.MODE_MULTI_PROCESS); // 여기

int localeIdx = preference.getInt(“testKey”, -1);

 

코드상으로는 MODE_PRIVATE | MODE_MULTI_PROCESS 이렇게 해주는 좋을것 같으나,

정의를 보면 MODE_PRIVATE 가 0으로 정의되어 있어서 그냥 MODE_MULTI_PROCESS 만 적어주었다.

 

public static final int MODE_PRIVATE = 0x0000;

public static final int MODE_MULTI_PROCESS = 0x0004;

 

참고 : http://developer.android.com/reference/android/content/Context.html#MODE_MULTI_PROCESS

 

 

 



: