Register now for Android Dev Summit 2019!

저장된 값 사용   Part of Android Jetpack.

이 주제에서는 Preference 라이브러리에서 저장된 Preference 값을 저장하고 사용하는 방법을 설명합니다.

기본 설정 데이터 스토리지

이 섹션에서는 Preference에서 데이터를 유지하는 방법을 설명합니다.

SharedPreferences

기본적으로 Preference는 값을 저장할 때 SharedPreferences 를 사용합니다. SharedPreferences API를 사용하면 애플리케이션 세션에 저장된 파일에서 간단한 키-값 쌍을 읽고 쓸 수 있습니다. Preference 라이브러리는 개발자의 애플리케이션만 액세스할 수 있도록 비공개 SharedPreferences 인스턴스를 사용합니다.

예를 들어 다음과 같이 SwitchPreferenceCompat가 있다고 생각해보세요.

<SwitchPreferenceCompat
        app:key="notifications"
        app:title="Enable message notifications"/>

사용자가 스위치를 On 상태로 바꾸면 SharedPreferences 파일이 "notifications" : "true"의 키-값 쌍으로 업데이트됩니다. 참고로 사용한 키는 Preference에 대한 키 세트와 동일합니다.

SharedPreferences API에 대한 자세한 내용은 키-값 데이터 저장을 참조하세요.

Android에서 데이터를 저장하는 다양한 방법에 대한 정보는 데이터 및 파일 스토리지 개요를 참조하세요.

PreferenceDataStore

Preference 라이브러리는 기본적으로 SharedPreferences를 사용하여 데이터를 유지하지만 SharedPreferences가 최적의 선택이 아닐 때도 있습니다. 예를 들어 애플리케이션에서 사용자의 로그인을 요구할 경우 모든 다른 기기와 플랫폼에도 설정이 반영되도록 클라우드에서 애플리케이션 설정을 유지하고 싶을 수도 있습니다. 마찬가지로 애플리케이션에 기기별 구성 옵션이 있을 경우 해당 기기의 각 사용자는 별도의 설정을 가지게 되므로 이 경우에는 SharedPreferences가 그다지 이상적인 솔루션이 아닙니다.

PreferenceDataStore는 맞춤 스토리지 백엔드를 사용하여 Preference 값을 유지하게 해줍니다. 자세한 내용은 맞춤 데이터 스토어 사용을 참조하세요.

기본 설정 값 읽기

사용 중인 SharedPreferences 개체를 검색하려면 PreferenceManager.getDefaultSharedPreferences()를 호출합니다. 이 메서드는 애플리케이션 어디서나 작동합니다. 예를 들어 "signature"라는 키가 포함된 EditTextPreference가 있습니다.

<EditTextPreference
        app:key="signature"
        app:title="Your signature"/>

Preference의 저장된 값은 다음과 같이 전역에서 검색할 수 있습니다.

Kotlin

val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this /* Activity context */)
val name = sharedPreferences.getString("signature", "")

Java

SharedPreferences sharedPreferences =
        PreferenceManager.getDefaultSharedPreferences(this /* Activity context */);
String name = sharedPreferences.getString(“signature”, "");

기본 설정 값 변경 사항 수신

Preference 값의 변경 사항을 수신할 때는 다음의 두 인터페이스 중 하나를 선택할 수 있습니다.

아래의 표는 두 인터페이스의 차이가 무엇인지 보여줍니다.

OnPreferenceChangeListener OnSharedPreferenceChangeListener
기본 설정별로 설정 모든 기본 설정에 적용
기본 설정이 저장된 값을 변경하려고 할 때 호출됩니다. 여기에는 대기 중인 값이 현재 저장된 값과 동일한 경우도 포함됩니다. 기본 설정에 저장된 값이 변경되었을 때만 호출됩니다.
Preference 라이브러리를 통해서만 호출됩니다. 애플리케이션의 별도 부분은 저장된 값을 변경할 수 있습니다. 저장된 값이 변경될 때마다 호출됩니다. 애플리케이션의 별도 부분에서일 경우에도 포함됩니다.
대기 중인 값이 저장되기 전에 호출됩니다. 값이 이미 저장된 후에 호출됩니다.
SharedPreferences 또는 PreferenceDataStore를 사용할 때 호출됩니다. SharedPreferences를 사용할 때만 호출됩니다.

OnPreferenceChangeListener

OnPreferenceChangeListener를 구현하면 Preference의 값이 변경되려고 할 때 이를 수신할 수 있습니다. 여기에서 이 변경 사항이 적용되어야 하는지 검증할 수 있습니다. 예를 들어 아래의 코드는 "name"이라는 키가 포함된 EditTextPreference의 값에 대한 변경 사항을 수신하는 방법을 보여줍니다.

Kotlin

override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
    Log.e("preference", "Pending Preference value is: $newValue")
    return true
}

Java

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
    Log.e("preference", "Pending Preference value is: " + newValue);
    return true;
}

그 다음에는 아래와 같이 setOnPreferenceChangeListener() 로 직접 이 리스너를 설정해야 합니다.

Kotlin

preference.onPreferenceChangeListener = ...

Java

preference.setOnPreferenceChangeListener(...);

OnSharedPreferenceChangeListener

SharedPreferences를 사용하여 Preference 값을 유지할 때 변경 사항을 수신하려면 SharedPreferences.OnSharedPreferenceChangeListener를 사용할 수도 있습니다. Preference가 저장한 값이 변경될 때(예: 설정과 서버 동기화) 이를 수신할 수 있습니다. 아래의 예시는 "name"이라는 키가 포함된 EditTextPreference의 값이 변경될 때 이를 수신하는 방법을 보여줍니다.

Kotlin

override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
    if (key == "signature") {
        Log.i(TAG, "Preference value was updated to: " + sharedPreferences.getString(key, ""))
    }
}

Java

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    if (key.equals(“signature”)) {
        Log.i(TAG, “Preference value was updated to: “ + sharedPreferences.getString(key, ""));
    }
}

또한 아래와 같이 registerOnSharedPreferenceChangedListener() 를 통해 리스너를 등록해야 합니다.

Kotlin

preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(...)

Java

getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(...);

Kotlin

val listener: SharedPreferences.OnSharedPreferenceChangeListener =
        SharedPreferences.OnSharedPreferenceChangeListener {...}

Java

SharedPreferences.OnSharedPreferenceChangeListener listener =
        new SharedPreferences.OnSharedPreferenceChangeListener() {...}

Activity 또는 Fragment에서 적절히 수명 주기를 관리하려면 아래와 같이 onResume()onPause() 콜백에서 이 리스너를 등록 및 등록 취소해야 합니다.

Kotlin

override fun onResume() {
    super.onResume()
    preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
}

override fun onPause() {
    super.onPause()
    preferenceManager.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
}

Java

@Override
public void onResume() {
    super.onResume();
    getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}

@Override
public void onPause() {
    super.onPause();
    getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}

맞춤 데이터 스토어 사용

SharedPreferences를 사용하여 Preference 개체를 유지하는 것을 권장하기는 하지만 맞춤 데이터 스토어도 사용할 수 있습니다. 맞춤 데이터 스토어는 애플리케이션이 데이터베이스에 대한 값을 유지하거나 기기별로 값이 다를 경우 유용할 수 있습니다.

데이터 스토어 구현

먼저 맞춤 데이터 스토어를 구현하려면 먼저 PreferenceDataStore를 확장하는 클래스를 생성합니다. 아래의 예시에서는 String 값을 처리하는 데이터 스토어를 만듭니다.

Kotlin

class DataStore : PreferenceDataStore() {
    override fun putString(key: String, @Nullable value: String) {
        // Save the value somewhere
    }

    @Nullable
    override fun getString(key: String, @Nullable defValue: String): String {
        // Retrieve the value
    }
}

Java

public class DataStore extends PreferenceDataStore {
    @Override
    public void putString(String key, @Nullable String value) {
        // Save the value somewhere
    }
    @Override
    @Nullable
    public String getString(String key, @Nullable String defValue) {
        // Retrieve the value
    }
}

사용자 인터페이스를 차단하지 않으려면 메인 스레드에서 시간이 오래 걸리는 작업을 덜어주세요. 값이 유지되는 동안 데이터 스토어가 포함된 Fragment 또는 Activity를 파괴할 수 있기 때문에 사용자가 변경한 값을 잃어버리지 않도록 데이터를 직렬화해야 합니다.

데이터 스토어 활성화

데이터 스토어를 구현한 다음에는 Preference 개체가 기본 SharedPreferences를 사용하는 대신 데이터 스토어로 값을 유지할 수 있도록 onCreatePreferences()에서 새 데이터 스토어를 설정해야 합니다. 데이터 스토어는 각 Preference 또는 전체 계층 구조에 대해 활성화할 수 있습니다.

특정 Preference에 대해 맞춤 데이터 스토어를 활성화하려면 아래의 예시와 같이 Preference에서 setPreferenceDataStore() 를 호출합니다.

Kotlin

val preference = findPreference("key")
preference.preferenceDataStore = dataStore

Java

Preference preference = findPreference(“key”);
preference.setPreferenceDataStore(dataStore);

전체 계층 구조에 대해 맞춤 데이터 스토어를 활성화하려면 PreferenceManager에서 setPreferenceDataStore()를 호출합니다.

Kotlin

val preferenceManager = preferenceManager
preferenceManager.preferenceDataStore = dataStore

Java

PreferenceManager preferenceManager = getPreferenceManager();
preferenceManager.setPreferenceDataStore(dataStore);

특정 Preference에 대해 설정된 데이터 스토어는 해당 계층 구조에 대해 설정된 모든 데이터 스토어를 재정의합니다. 대부분의 경우 전체 계층 구조에 대해 데이터 스토어를 설정해야 합니다.