저장된 환경설정 값 사용 Android Jetpack의 구성요소

이 문서에서는 환경설정 라이브러리에서 저장한 Preference 값을 저장하고 사용하는 방법을 설명합니다.

환경설정 데이터 저장소

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

SharedPreferences

기본적으로 PreferenceSharedPreferences를 사용하여 값을 저장합니다. SharedPreferences API는 애플리케이션 세션에 저장된 파일에서 간단한 키-값 쌍을 읽고 쓸 수 있도록 지원합니다. 환경설정 라이브러리는 비공개 SharedPreferences 인스턴스를 사용하므로 내 애플리케이션만 인스턴스에 액세스할 수 있습니다.

예를 들어 다음과 같은 SwitchPreferenceCompat가 있다고 가정합니다.

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

사용자가 이 스위치를 '켜짐' 상태로 전환하면 SharedPreferences 파일이 "notifications" : "true"의 키-값 쌍으로 업데이트됩니다. 사용되는 키는 Preference에 설정된 키와 동일합니다.

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

Android에서 데이터를 저장하는 다양한 방법에 관한 자세한 내용은 데이터 및 파일 저장소 개요를 참고하세요.

PreferenceDataStore

환경설정 라이브러리는 기본적으로 SharedPreferences를 사용하여 데이터를 유지하지만 SharedPreferences가 항상 이상적인 솔루션은 아닙니다. 예를 들어 애플리케이션에서 사용자가 로그인해야 하는 경우 설정이 다른 기기 및 플랫폼에 반영되도록 클라우드에 애플리케이션 설정을 유지할 수 있습니다. 마찬가지로 애플리케이션에 기기별 구성 옵션이 있다면 기기의 각 사용자가 별도의 설정을 갖게 되므로 SharedPreferences는 이상적인 해결 방법이 아닙니다.

PreferenceDataStore를 사용하면 맞춤 저장소 백엔드를 사용하여 Preference 값을 유지할 수 있습니다. 자세한 내용은 커스텀 Datastore 사용을 참조하세요.

환경설정 값 읽기

사용 중인 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에 설정됩니다. 모든 Preference 객체에 적용됩니다.
대기 중인 값이 저장된 값과 같은 경우에도 Preference가 저장된 값을 변경하려고 할 때 호출됩니다. Preference에 저장된 값이 변경될 때만 호출됩니다.
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 객체를 유지하는 것이 좋지만 커스텀 Datastore를 사용할 수도 있습니다. 커스텀 데이터 스토어는 다음 예시와 같이 애플리케이션이 값을 데이터베이스에 유지하거나 값이 기기별일 때 유용할 수 있습니다.

데이터 스토어 구현

맞춤 데이터 스토어를 구현하려면 PreferenceDataStore를 확장하는 클래스를 만듭니다. 다음 예시에서는 String 값을 처리하는 Datastore를 만듭니다.

Kotlin

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

    override fun getString(key: String, 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.
    }
}

사용자 인터페이스가 차단되지 않도록 기본 스레드 밖에서 시간이 오래 걸리는 작업을 실행하세요. 값을 유지하는 동안 Datastore를 포함하는 Fragment 또는 Activity가 소멸될 수 있으므로 사용자가 변경한 값을 잃지 않도록 데이터를 직렬화합니다.

데이터 저장소 사용 설정

Datastore를 구현한 후에는 Preference 객체가 기본 SharedPreferences를 사용하지 않고 Datastore에 값을 유지하도록 onCreatePreferences()에 새 Datastore를 설정합니다. 각 Preference 또는 전체 계층 구조에서 Datastore를 사용 설정할 수 있습니다.

특정 Preference에 커스텀 Datastore를 사용 설정하려면 다음 예시와 같이 PreferencesetPreferenceDataStore()를 호출합니다.

Kotlin

val preference: Preference? = findPreference("key")
preference?.preferenceDataStore = dataStore

Java

Preference preference = findPreference("key");
if (preference != null) {
    preference.setPreferenceDataStore(dataStore);
}

전체 계층 구조에 커스텀 Datastore를 사용 설정하려면 PreferenceManager에서 setPreferenceDataStore()를 호출합니다.

Kotlin

val preferenceManager = preferenceManager
preferenceManager.preferenceDataStore = dataStore

Java

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

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