Usa i valori di preferenza salvati Parte di Android Jetpack.

Questo documento descrive come archiviare e utilizzare i valori di Preference salvati dalla libreria di preferenze.

Archiviazione dei dati preferiti

Questa sezione descrive in che modo un Preference può salvare i dati.

Preferenze condivise

Per impostazione predefinita, un Preference utilizza SharedPreferences per salvare i valori. L'API SharedPreferences supporta la lettura e la scrittura di semplici coppie chiave-valore da un file salvato in più sessioni dell'applicazione. La libreria di preferenze utilizza un'istanza SharedPreferences privata in modo che solo la tua applicazione possa accedervi.

Supponiamo, ad esempio, che si supponga quanto segue SwitchPreferenceCompat:

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

Quando un utente attiva l'opzione, il file SharedPreferences viene aggiornato con una coppia chiave-valore "notifications" : "true". La chiave utilizzata è uguale a quella impostata per Preference.

Per ulteriori informazioni sull'API SharedPreferences, consulta Salvare i dati delle coppie chiave-valore.

Per informazioni sulle diverse modalità di archiviazione dei dati su Android, consulta Panoramica sull'archiviazione di dati e file.

PreferenceDataStore

Anche se la libreria Preference conserva i dati con SharedPreferences per impostazione predefinita, SharedPreferences non è sempre una soluzione ideale. Ad esempio, se la tua applicazione richiede che un utente esegua l'accesso, è consigliabile mantenere le impostazioni dell'applicazione nel cloud in modo che si riflettano su altri dispositivi e piattaforme. Analogamente, se l'applicazione dispone di opzioni di configurazione specifiche per il dispositivo, ogni utente sul dispositivo avrà impostazioni separate, il che rende SharedPreferences una soluzione non ideale.

Un PreferenceDataStore consente di utilizzare un backend di archiviazione personalizzato per salvare i valori Preference. Per ulteriori informazioni, consulta Utilizzare un datastore personalizzato.

Lettura valori preferenza

Per recuperare l'oggetto SharedPreferences in uso, chiama PreferenceManager.getDefaultSharedPreferences(). Anche se questo metodo funziona da qualsiasi punto dell'applicazione, ti consigliamo di dividere l'app in livelli. Per ulteriori informazioni, consulta Livello dati.

Ad esempio, se viene fornito un valore EditTextPreference con una chiave di "signature", come segue:

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

Puoi recuperare il valore salvato per questo Preference a livello globale, come segue:

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

Monitora le modifiche ai valori di preferenza

Per esaminare le modifiche ai valori Preference, puoi scegliere tra due interfacce:

La seguente tabella mostra le differenze tra le due interfacce:

OnPreferenceChangeListener OnSharedPreferenceChangeListener
Impostato su un singolo Preference. Si applica a tutti i Preference oggetti.
Richiamato quando un Preference sta per modificare il suo valore salvato, anche se il valore in sospeso è uguale a quello salvato. Richiamato solo quando cambia il valore salvato per Preference.
Chiamate solo tramite la raccolta Preference. Una parte separata dell'applicazione può modificare il valore salvato. Richiamato ogni volta che il valore salvato cambia, anche se proviene da una parte separata dell'applicazione.
Chiamato prima del salvataggio del valore in attesa. Richiamato dopo il salvataggio del valore.
Richiamato se utilizzi SharedPreferences o PreferenceDataStore. Chiamata solo quando si utilizza SharedPreferences.

Implementare OnPreferenceChangeListener

L'implementazione di un OnPreferenceChangeListener consente di rimanere in ascolto di una modifica in attesa del valore di Preference. Quindi, puoi verificare se la modifica avrà luogo. Ad esempio, il codice seguente mostra come rimanere in ascolto di una modifica del valore di EditTextPreference con una chiave di "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;
}

A questo punto, devi impostare il listener direttamente con setOnPreferenceChangeListener() come segue:

Kotlin

preference.onPreferenceChangeListener = ...

Java

preference.setOnPreferenceChangeListener(...);

Implementare OnSharedPreferenceChangeListener

Quando i valori Preference vengono resi persistenti utilizzando SharedPreferences, puoi anche utilizzare un SharedPreferences.OnSharedPreferenceChangeListener per rimanere in ascolto delle modifiche. In questo modo puoi rimanere in ascolto per capire quando i valori salvati da Preference vengono modificati, ad esempio durante la sincronizzazione delle impostazioni con un server. L'esempio seguente mostra come ascoltare una modifica al valore di EditTextPreference con la chiave "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, ""));
    }
}

Registra il listener utilizzando registerOnSharedPreferenceChangedListener() come segue:

Kotlin

preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(...)

Java

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

Kotlin

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

Java

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

Per una corretta gestione del ciclo di vita in Activity o Fragment, registra e annulla la registrazione di questo listener nei callback onResume() e onPause(), come mostrato nell'esempio seguente:

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

Utilizza un datastore personalizzato

Anche se è consigliabile salvare gli oggetti Preference in modo permanente utilizzando SharedPreferences, puoi anche utilizzare un datastore personalizzato. Un datastore personalizzato può essere utile se l'applicazione rende persistenti i valori in un database o se i valori sono specifici per dispositivo, come mostrato negli esempi seguenti.

Implementazione del datastore

Per implementare un datastore personalizzato, crea una classe che estenda PreferenceDataStore. L'esempio seguente crea un datastore che gestisce i valori 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.
    }
}

Esegui operazioni che richiedono tempo dal thread principale per evitare di bloccare l'interfaccia utente. Poiché è possibile che Fragment o Activity contenente il datastore vengano eliminati mentre viene mantenuto un valore, serializza i dati in modo da non perdere i valori modificati dall'utente.

Abilita il datastore

Dopo aver implementato il datastore, imposta il nuovo datastore in onCreatePreferences() in modo che gli oggetti Preference rimangano valori nel datastore anziché utilizzare il valore predefinito SharedPreferences. Puoi abilitare un datastore per ogni Preference o per l'intera gerarchia.

Per attivare un datastore personalizzato per un Preference specifico, chiama setPreferenceDataStore() sul Preference, come mostrato nell'esempio seguente:

Kotlin

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

Java

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

Per attivare un datastore personalizzato per un'intera gerarchia, chiama setPreferenceDataStore() sul PreferenceManager:

Kotlin

val preferenceManager = preferenceManager
preferenceManager.preferenceDataStore = dataStore

Java

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

Un datastore impostato per un valore Preference specifico sostituisce qualsiasi datastore impostato per la gerarchia corrispondente. Nella maggior parte dei casi, imposti un datastore per l'intera gerarchia.