Menggunakan nilai Preference tersimpan Bagian dari Android Jetpack.

Dokumen ini menjelaskan cara menyimpan dan menggunakan nilai Preference yang disimpan oleh library Preference.

Penyimpanan data Preference

Bagian ini menjelaskan bagaimana sebuah Preference dapat menyimpan data.

SharedPreferences

Secara default, Preference menggunakan SharedPreferences untuk menyimpan nilai. SharedPreferences API mendukung pembacaan dan penulisan key-value pair sederhana dari file yang disimpan di seluruh sesi aplikasi. Library Preference menggunakan instance SharedPreferences pribadi sehingga hanya aplikasi Anda yang dapat mengaksesnya.

Sebagai contoh, asumsikan SwitchPreferenceCompat berikut:

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

Saat pengguna mengalihkan tombol ini ke status "aktif", file SharedPreferences akan diperbarui dengan pasangan nilai kunci "notifications" : "true". Kunci yang digunakan sama dengan kunci yang ditetapkan untuk Preference.

Untuk mengetahui informasi selengkapnya tentang SharedPreferences API, lihat Menyimpan data nilai kunci.

Untuk mengetahui informasi tentang berbagai cara menyimpan data di Android, lihat Ringkasan penyimpanan data dan file.

PreferenceDataStore

Meskipun library Preference mempertahankan data menggunakan SharedPreferences secara default, SharedPreferences tidak selalu merupakan solusi ideal. Misalnya, jika aplikasi Anda mengharuskan pengguna untuk login, sebaiknya pertahankan setelan aplikasi di cloud agar setelan tersebut diterapkan di seluruh perangkat dan platform lainnya. Demikian pula, jika aplikasi Anda memiliki opsi konfigurasi yang berlaku untuk perangkat tertentu, setiap pengguna di perangkat tersebut memiliki setelan terpisah, sehingga menjadikan SharedPreferences sebagai solusi yang kurang ideal.

PreferenceDataStore memungkinkan Anda menggunakan backend penyimpanan kustom untuk mempertahankan nilai Preference. Untuk mengetahui informasi selengkapnya, lihat Menggunakan datastore kustom.

Membaca nilai Preference

Untuk mengambil objek SharedPreferences yang sedang digunakan, panggil PreferenceManager.getDefaultSharedPreferences(). Meskipun metode ini berfungsi dari mana pun dalam aplikasi, sebaiknya Anda membagi aplikasi menjadi beberapa lapisan. Untuk mengetahui informasi selengkapnya, lihat Lapisan data.

Misalnya, dengan EditTextPreference yang memiliki kunci "signature", seperti berikut:

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

Anda dapat mengambil nilai tersimpan untuk Preference ini secara global, seperti berikut:

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", "");

Memproses perubahan nilai Preference

Untuk memproses perubahan nilai Preference, Anda dapat memilih antara dua antarmuka:

Tabel berikut menunjukkan perbedaan antara kedua antarmuka:

OnPreferenceChangeListener OnSharedPreferenceChangeListener
Ditetapkan di satu Preference. Berlaku untuk semua objek Preference.
Dipanggil saat Preference akan mengubah nilai tersimpannya, meskipun nilai yang tertunda sama dengan nilai yang disimpan. Hanya dipanggil saat nilai yang disimpan untuk Preference berubah.
Hanya dipanggil melalui library Preference. Bagian aplikasi yang terpisah dapat mengubah nilai tersimpan. Dipanggil setiap kali nilai tersimpan berubah, meskipun nilai tersebut berasal dari bagian aplikasi yang terpisah.
Dipanggil sebelum nilai tertunda disimpan. Dipanggil setelah nilai disimpan.
Dipanggil saat menggunakan SharedPreferences atau PreferenceDataStore. Hanya dipanggil saat menggunakan SharedPreferences.

Menerapkan OnPreferenceChangeListener

Dengan mengimplementasikan OnPreferenceChangeListener, Anda dapat memproses perubahan dalam proses terhadap nilai Preference. Kemudian, Anda dapat memvalidasi apakah perubahan terjadi. Misalnya, kode berikut menunjukkan cara memproses perubahan nilai EditTextPreference dengan kunci "name":

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;
}

Selanjutnya, Anda perlu menetapkan pemroses ini langsung dengan setOnPreferenceChangeListener(), seperti berikut:

Kotlin

preference.onPreferenceChangeListener = ...

Java

preference.setOnPreferenceChangeListener(...);

Mengimplementasikan OnSharedPreferenceChangeListener

Jika nilai Preference dipertahankan menggunakan SharedPreferences, Anda juga dapat menggunakan SharedPreferences.OnSharedPreferenceChangeListener untuk memproses perubahan. Hal ini memungkinkan Anda memproses kapan nilai yang disimpan oleh Preference berubah, seperti saat menyinkronkan setelan dengan server. Contoh berikut menunjukkan cara memproses perubahan nilai EditTextPreference dengan kunci "name":

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, ""));
    }
}

Daftarkan pemroses menggunakan registerOnSharedPreferenceChangedListener(), sebagai berikut:

Kotlin

preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(...)

Java

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

Kotlin

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

Java

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

Untuk pengelolaan siklus proses yang tepat di Activity atau Fragment, daftarkan dan batalkan pendaftaran pemroses ini dalam callback onResume() dan onPause(), seperti ditunjukkan dalam contoh berikut:

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);
}

Menggunakan datastore kustom

Meskipun kami merekomendasikan untuk mempertahankan objek Preference menggunakan SharedPreferences, Anda juga dapat menggunakan datastore kustom. Datastore kustom dapat berguna jika aplikasi Anda mempertahankan nilai ke database atau jika nilai tersebut berlaku untuk perangkat tertentu, seperti yang ditunjukkan pada contoh berikut.

Mengimplementasikan datastore

Untuk mengimplementasikan datastore kustom, buat class yang memperluas PreferenceDataStore. Contoh berikut membuat datastore yang menangani nilai String:

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.
    }
}

Jalankan operasi apa pun yang memakan waktu di luar thread utama untuk menghindari pemblokiran antarmuka pengguna. Karena Fragment atau Activity yang berisi datastore dapat dihancurkan saat mempertahankan nilai, lakukan serialisasi data sehingga Anda tidak kehilangan nilai apa pun yang diubah oleh pengguna.

Mengaktifkan datastore

Setelah Anda mengimplementasikan datastore, tetapkan datastore baru di onCreatePreferences() sehingga objek Preference mempertahankan nilai dengan datastore, bukan menggunakan SharedPreferences default. Anda dapat mengaktifkan datastore untuk setiap Preference atau untuk seluruh hierarki.

Untuk mengaktifkan datastore kustom untuk Preference tertentu, panggil setPreferenceDataStore() pada Preference, seperti ditunjukkan dalam contoh berikut:

Kotlin

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

Java

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

Guna mengaktifkan datastore kustom untuk seluruh hierarki, panggil setPreferenceDataStore() pada PreferenceManager:

Kotlin

val preferenceManager = preferenceManager
preferenceManager.preferenceDataStore = dataStore

Java

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

Datastore yang ditetapkan untuk Preference tertentu akan menggantikan datastore apa pun yang ditetapkan untuk hierarki yang sesuai. Pada kebanyakan kasus, Anda menetapkan datastore untuk seluruh hierarki.