Android SharedPreferences 모범 사례
내가 빌드 한 애플리케이션에서 우리는 SharedPreferences에 상당히 의존하고 있습니다. 이것은 SharedPreferences에 액세스 할 때 가장 좋은 방법이 무엇인지 생각하게했습니다. 예를 들어 많은 사람들은 다음 호출을 통해 액세스하는 적절한 방법을 말합니다.
PreferenceManager.getDefaultSharedPreferences(Context context)
그러나 이것은 위험 할 수있는 것 같습니다. SharedPreferences에 의존하는 대규모 애플리케이션이있는 경우 특히 SharedPreferences에 의존하는 일부 타사 라이브러리를 사용하는 경우 키가 중복 될 수 있습니다. 사용하는 더 나은 호출은 다음과 같습니다.
Context.getSharedPreferences(String name, int mode)
이렇게하면 SharedPreferences에 크게 의존하는 클래스가있는 경우 해당 클래스에서만 사용되는 환경 설정 파일을 만들 수 있습니다. 클래스의 정규화 된 이름을 사용하여 파일이 다른 사람에 의해 복제되지 않도록 할 수 있습니다.
또한이 SO 질문을 기반으로 : SharedPreferences에 액세스하는 것이 UI 스레드에서 수행되어야합니까? , SharedPreferences에 액세스하는 것은 의미가있는 UI 스레드에서 수행되어야하는 것 같습니다.
Android 개발자가 애플리케이션에서 SharedPreferences를 사용할 때 알아야 할 다른 모범 사례가 있습니까?
SharedPreferences에 의존하는 대규모 애플리케이션이있는 경우 특히 SharedPreferences에 의존하는 일부 타사 라이브러리를 사용하는 경우 키 중복이 발생할 수 있습니다.
도서관은 특정 SharedPreferences
. 기본값 SharedPreferences
은 응용 프로그램에서만 사용해야합니다.
이렇게하면 SharedPreferences에 크게 의존하는 클래스가있는 경우 해당 클래스에서만 사용되는 환경 설정 파일을 만들 수 있습니다.
당신은 확실히 이것을 할 수 있습니다. 응용 프로그램 수준에서는 응용 프로그램 SharedPreferences
의 구성 요소간에 공유하는 것이 주된 이유이므로 그렇지 않습니다 . 개발 팀은 클래스, 패키지, 리소스 또는 기타 프로젝트 수준의 항목을 관리하는 데 문제가 없어야하는 것처럼이 네임 스페이스를 관리하는 데 문제가 없어야합니다. 또한 기본값 SharedPreferences
은 PreferenceActivity
사용할 것입니다.
그러나 라이브러리 지점으로 돌아 가면 재사용 가능한 라이브러리는 SharedPreferences
라이브러리에만 별도의 라이브러리를 사용해야합니다 . 클래스 이름을 기반으로하지 않을 것입니다. 왜냐하면 당신은 당신의 앱을 깨뜨리는 것을 리팩토링하는 사람이기 때문입니다. 대신 고유하지만 (예 : 같은 라이브러리 이름을 기반으로 함 "com.commonsware.cwac.wakeful.WakefulIntentService"
) 안정적인 이름을 선택하십시오 .
SharedPreferences에 액세스하는 것은 의미있는 UI 스레드에서 수행되어야하는 것 같습니다.
이상적으로는 그렇습니다. 나는 최근 SharedPreferencesLoader
에 이것에 도움이 되는를 출시했습니다 .
Android 개발자가 애플리케이션에서 SharedPreferences를 사용할 때 알아야 할 다른 모범 사례가 있습니까?
그들에게 지나치게 의존하지 마십시오. XML 파일에 저장되며 트랜잭션이 아닙니다. 데이터베이스는 특히 손실을 원하지 않는 데이터에 대한 기본 데이터 저장소 여야합니다.
여기 에서도 찾을 수있는 작은 기사를 썼습니다 . 그것은 무엇을 설명합니다 SharedPreferences
:
모범 사례 : SharedPreferences
Android는 애플리케이션 데이터를 저장하는 다양한 방법을 제공합니다. 이러한 방법 중 하나는 키-값 쌍에 개인용 기본 데이터를 저장하는 데 사용되는 SharedPreferences 객체로 연결됩니다.
모든 논리는 세 가지 간단한 클래스에만 기반합니다.
SharedPreferences
SharedPreferences
그들의 주요입니다. 저장된 데이터를 가져 오는 (파싱)을 담당하고 Editor
객체 를 가져 오는 인터페이스와 추가 및 제거를위한 인터페이스를 제공OnSharedPreferenceChangeListener
- 만들려면 개체
SharedPreferences
가 필요Context
합니다 (응용 프로그램 일 수 있음Context
) getSharedPreferences
메소드는 환경 설정 파일을 구문 분석하고 이에Map
대한 객체를 생성 합니다.Context에서 제공하는 몇 가지 모드로 만들 수 있습니다. 세계에서 읽을 수있는 / 쓰기 가능한 파일을 만드는 것은 매우 위험하고 응용 프로그램에 보안 허점을 일으킬 수 있으므로 MODE_PRIVATE를 사용하는 것이 좋습니다.
// parse Preference file SharedPreferences preferences = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE); // get values from Map preferences.getBoolean("key", defaultValue) preferences.get..("key", defaultValue) // you can get all Map but be careful you must not modify the collection returned by this // method, or alter any of its contents. Map<String, ?> all = preferences.getAll(); // get Editor object SharedPreferences.Editor editor = preferences.edit(); //add on Change Listener preferences.registerOnSharedPreferenceChangeListener(mListener); //remove on Change Listener preferences.unregisterOnSharedPreferenceChangeListener(mListener); // listener example SharedPreferences.OnSharedPreferenceChangeListener mOnSharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() { @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { } };
편집자
SharedPreferences.Editor
SharedPreferences
객체의 값을 수정하는 데 사용되는 인터페이스 입니다. 편집기에서 변경 한 모든 내용은 일괄 처리되며 SharedPreferences
commit () 또는 apply ()를 호출 할 때까지 원본으로 다시 복사되지 않습니다.
- 간단한 인터페이스를 사용하여 값을 입력하십시오.
Editor
- 더 빠른 동기
commit()
또는 비동기 값을 저장합니다apply
. 실제로 사용하는 다른 스레드를 사용하는commit()
것이 더 안전합니다. 그래서commit()
. 단일 값 제거
remove()
또는 모든 값 지우기clear()
// get Editor object SharedPreferences.Editor editor = preferences.edit(); // put values in editor editor.putBoolean("key", value); editor.put..("key", value); // remove single value by key editor.remove("key"); // remove all values editor.clear(); // commit your putted values to the SharedPreferences object synchronously // returns true if success boolean result = editor.commit(); // do the same as commit() but asynchronously (faster but not safely) // returns nothing editor.apply();
성능 및 팁
SharedPreferences
는 Singleton 객체이므로 원하는만큼의 참조를 쉽게 얻을 수 있으며getSharedPreferences
처음 호출 할 때만 파일을 열거 나 참조를 하나만 만들 수 있습니다.// There are 1000 String values in preferences SharedPreferences first = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE); // call time = 4 milliseconds SharedPreferences second = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE); // call time = 0 milliseconds SharedPreferences third = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE); // call time = 0 milliseconds
마찬가지로
SharedPreferences
A는 싱글 톤 객체는 그것의 인스턴스를 변경할 수 있습니다 자신의 데이터가 다를 수 있음을 무서워하지first.edit().putInt("key",15).commit(); int firstValue = first.getInt("key",0)); // firstValue is 15 int secondValue = second.getInt("key",0)); // secondValue is also 15
환경 설정 객체가 더 이상 큰 기억
get
,commit
,apply
,remove
및clear
작업이 될 것입니다. 따라서 서로 다른 작은 개체에서 데이터를 분리하는 것이 좋습니다.응용 프로그램 업데이트 후에도 기본 설정 은 제거되지 않습니다 . 따라서 마이그레이션 계획을 만들어야하는 경우가 있습니다. 예를 들어 응용 프로그램 시작시 로컬 JSON을 구문 분석하는 응용 프로그램이 있으며 처음 시작한 후에 만이 작업을 수행하려면 부울 플래그를 저장하기로 결정했습니다
wasLocalDataLoaded
. 얼마 후 해당 JSON을 업데이트하고 새 애플리케이션 버전을 출시했습니다. 사용자는 애플리케이션을 업데이트하지만 첫 번째 애플리케이션 버전에서 이미 수행 했으므로 새 JSON을로드하지 않습니다.public class MigrationManager { private final static String KEY_PREFERENCES_VERSION = "key_preferences_version"; private final static int PREFERENCES_VERSION = 2; public static void migrate(Context context) { SharedPreferences preferences = context.getSharedPreferences("pref", Context.MODE_PRIVATE); checkPreferences(preferences); } private static void checkPreferences(SharedPreferences thePreferences) { final double oldVersion = thePreferences.getInt(KEY_PREFERENCES_VERSION, 1); if (oldVersion < PREFERENCES_VERSION) { final SharedPreferences.Editor edit = thePreferences.edit(); edit.clear(); edit.putInt(KEY_PREFERENCES_VERSION, currentVersion); edit.commit(); } } }
SharedPreferences
앱 데이터 폴더의 xml 파일에 저장됩니다.// yours preferences /data/data/YOUR_PACKAGE_NAME/shared_prefs/YOUR_PREFS_NAME.xml // default preferences /data/data/YOUR_PACKAGE_NAME/shared_prefs/YOUR_PACKAGE_NAME_preferences.xml
샘플 코드
public class PreferencesManager {
private static final String PREF_NAME = "com.example.app.PREF_NAME";
private static final String KEY_VALUE = "com.example.app.KEY_VALUE";
private static PreferencesManager sInstance;
private final SharedPreferences mPref;
private PreferencesManager(Context context) {
mPref = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
}
public static synchronized void initializeInstance(Context context) {
if (sInstance == null) {
sInstance = new PreferencesManager(context);
}
}
public static synchronized PreferencesManager getInstance() {
if (sInstance == null) {
throw new IllegalStateException(PreferencesManager.class.getSimpleName() +
" is not initialized, call initializeInstance(..) method first.");
}
return sInstance;
}
public void setValue(long value) {
mPref.edit()
.putLong(KEY_VALUE, value)
.commit();
}
public long getValue() {
return mPref.getLong(KEY_VALUE, 0);
}
public void remove(String key) {
mPref.edit()
.remove(key)
.commit();
}
public boolean clear() {
return mPref.edit()
.clear()
.commit();
}
}
이게 내 방법이야
쓰기 위해
SharedPreferences settings = context.getSharedPreferences("prefs", 0);
SharedPreferences.Editor editore = settings.edit();
editore.putString("key", "some value");
editore.apply();
읽다
SharedPreferences settings = getSharedPreferences("prefs", 0);
Strings value = settings.getString("key", "");
kotlin에서는 SharedPreferences
다음과 같은 방법으로의 사용을 단순화 할 수 있습니다.
class Prefs(context: Context) {
companion object {
private const val PREFS_FILENAME = "app_prefs"
private const val KEY_MY_STRING = "my_string"
private const val KEY_MY_BOOLEAN = "my_boolean"
private const val KEY_MY_ARRAY = "string_array"
}
private val sharedPrefs: SharedPreferences =
context.getSharedPreferences(PREFS_FILENAME, Context.MODE_PRIVATE)
var myString: String
get() = sharedPrefs.getString(KEY_MY_STRING, "") ?: ""
set(value) = sharedPrefs.edit { putString(KEY_MY_STRING, value) }
var myBoolean: Boolean
get() = sharedPrefs.getBoolean(KEY_MY_BOOLEAN, false)
set(value) = sharedPrefs.edit { putBoolean(KEY_MY_BOOLEAN, value) }
var myStringArray: Array<String>
get() = sharedPrefs.getStringSet(KEY_MY_ARRAY, emptySet())?.toTypedArray()
?: emptyArray()
set(value) = sharedPrefs.edit { putStringSet(KEY_MY_ARRAY, value.toSet()) }
Here,
sharedPrefs.edit{...}
is provided by the android core ktx library and should be implemented by adding dependencyimplementation "androidx.core:core-ktx:1.0.2"
in appliation levelbuild.gradle
.
You can get the instance of SharedPreferences
by using code:
val prefs = Prefs(context)
Furthermore, you can create the Singleton
object of Prefs
and use from anywhere within the app.
val prefs: Prefs by lazy {
Prefs(App.instance)
}
where, App
extends Application
and should be included in AndroidManifest.xml
App.kt
class App:Application() {
companion object {
lateinit var instance: App
}
override fun onCreate() {
super.onCreate()
instance = this
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest .....
<application
android:name=".App"
....
Example Usage:
// get stored value
val myString = prefs.myString
// store value
prefs.myString = "My String Value"
// get stored array
val myStringArray = prefs.myStringArray
// store array
prefs.myStringArray = arrayOf("String 1","String 2","String 3")
Let's assume in a project, with multiple developers working on it, they are defining SharedPreference within an Activity like this:
SharedPreferences sharedPref = context.getSharedPreferences("prefName", 0);
At one point or another two developers can define the SharedPreference with the same name or insert equivalent Key - Value pairs, which will lead to problems in using the keys.
The solution relies on two options, whether to use;
SharedPreferences Singleton that uses String keys.
SharedPreferences Singleton that uses Enum keys.
Personally and According to this Sharepreference Documentation, I prefer to use Enum keys as it enforces stricter control when there are multiple programmers working on a project. A programmer has no choice but to declare a new key in the appropriate enum class and so all the keys are in the same place.
And to avoid boilerplate code writing create the SharedPreference singleton. This SharedPreferences singleton Class help to centralize and simplify reading and writing of SharedPreferences in your Android app.
The source code for the two provided solutions can be found in GitHub
ReferenceURL : https://stackoverflow.com/questions/8855069/android-sharedpreferences-best-practices
'developer tip' 카테고리의 다른 글
UNION 및 ORDER BY의 잘못된 사용? (0) | 2021.01.06 |
---|---|
Python에서 산 세척 이해하기 (0) | 2021.01.06 |
저장 프로 시저의 출력을 SQL Server의 변수로 반환하는 방법 (0) | 2021.01.06 |
코드 서명 ID 란 무엇입니까? (0) | 2021.01.06 |
C #에서 모든 컨트롤러 및 작업 이름 가져 오기 (0) | 2021.01.05 |