Usar valores de preferência salvos Parte do Android Jetpack
Este documento descreve como armazenar e usar
valores de Preference
que são salvos pela
biblioteca Preference.
Armazenamento de dados de preferências
Esta seção descreve como uma Preference
pode manter dados.
SharedPreferences
Por padrão, um Preference
usa
SharedPreferences
para salvar
valores. A API SharedPreferences
oferece suporte à leitura e gravação de pares
de chave-valor simples de um arquivo salvo nas sessões do aplicativo. A
biblioteca Preference usa uma instância particular de SharedPreferences
para que somente seu
aplicativo possa acessá-la.
Como exemplo, considere o seguinte
SwitchPreferenceCompat
:
<SwitchPreferenceCompat app:key="notifications" app:title="Enable message notifications"/>
Quando um usuário muda essa chave para o estado "ativado", o arquivo SharedPreferences
é atualizado com um par de chave-valor de "notifications" : "true"
. A chave usada é a
mesma definida para o Preference
.
Para mais informações sobre a API SharedPreferences
, consulte Salvar dados de
chave-valor.
Para ver informações sobre as diferentes maneiras de armazenar dados no Android, consulte Visão geral do armazenamento de dados e arquivos.
PreferenceDataStore
Embora a biblioteca Preference mantenha os dados com SharedPreferences
por
padrão, SharedPreferences
nem sempre é a solução ideal. Por exemplo, se
o aplicativo exige que o usuário faça login, mantenha
as configurações do aplicativo na nuvem para que elas sejam refletidas em
outros dispositivos e plataformas. Da mesma forma, se o aplicativo tiver opções de configuração
específicas do dispositivo, cada usuário no dispositivo terá configurações separadas,
tornando SharedPreferences
uma solução não ideal.
Um PreferenceDataStore
permite usar um back-end de armazenamento personalizado para manter os valores de Preference
. Para mais
informações, consulte Usar um armazenamento de dados personalizado.
Ler valores de preferência
Para recuperar o objeto SharedPreferences
que está sendo usado, chame
PreferenceManager.getDefaultSharedPreferences()
.
Embora esse método funcione em qualquer lugar do seu app, recomendamos
dividir o app em camadas. Para mais informações, consulte Camada de
dados.
Por exemplo, considerando um EditTextPreference
com uma chave de "signature"
, desta
maneira:
<EditTextPreference app:key="signature" app:title="Your signature"/>
Você pode recuperar o valor salvo para esse Preference
globalmente, da seguinte maneira:
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", "");
Detectar as mudanças nos valores de preferência
Para detectar mudanças em valores de Preference
, você pode escolher entre duas
interfaces:
A tabela a seguir mostra as diferenças entre as duas interfaces:
OnPreferenceChangeListener |
OnSharedPreferenceChangeListener |
---|---|
Definido em um único Preference . |
Aplica-se a todos os objetos Preference . |
Chamado quando um Preference está prestes a mudar o valor salvo,
mesmo que o valor pendente seja igual ao valor salvo. |
Chamado somente quando o valor salvo para uma Preference muda. |
Chamada somente pela biblioteca Preference . Uma parte separada
do aplicativo pode mudar o valor salvo. |
Chamado sempre que o valor salvo muda, mesmo que seja de uma parte separada do app. |
Chamada antes de o valor pendente ser salvo. | Chamado depois que o valor é salvo. |
Chamado ao usar SharedPreferences ou PreferenceDataStore . |
Chamada somente ao usar SharedPreferences . |
Implementar OnPreferenceChangeListener
A implementação de um OnPreferenceChangeListener
permite detectar uma mudança
pendente no valor de um Preference
. Em seguida, você pode validar se a mudança
ocorre. Por exemplo, o código a seguir mostra como detectar uma mudança no
valor de EditTextPreference
com uma chave de "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; }
Em seguida, você precisa definir esse listener diretamente com
setOnPreferenceChangeListener()
da seguinte maneira:
Kotlin
preference.onPreferenceChangeListener = ...
Java
preference.setOnPreferenceChangeListener(...);
Implementar OnSharedPreferenceChangeListener
Ao manter valores de Preference
usando SharedPreferences
, você também pode usar
um SharedPreferences.OnSharedPreferenceChangeListener
para detectar mudanças.
Isso permite que você detecte quando os valores salvos pelo Preference
mudam,
como ao sincronizar configurações com um servidor. O exemplo abaixo mostra como
detectar uma mudança no valor de EditTextPreference
com uma chave de
"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, "")); } }
Registre o listener usando
registerOnSharedPreferenceChangedListener()
,
da seguinte maneira:
Kotlin
preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(...)
Java
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(...);
Kotlin
val listener: SharedPreferences.OnSharedPreferenceChangeListener = SharedPreferences.OnSharedPreferenceChangeListener {...}
Java
SharedPreferences.OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener() {...}
Para um gerenciamento adequado do ciclo de vida em Activity
ou Fragment
, registre e
cancele o registro desse listener nos callbacks onResume()
e onPause()
, conforme mostrado
neste exemplo:
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); }
Usar um repositório de dados personalizado
Embora seja recomendável persistir objetos Preference
usando SharedPreferences
,
também é possível usar um repositório de dados personalizado. Um armazenamento de dados personalizado pode ser útil se o
aplicativo persistir valores em um banco de dados ou se os valores forem específicos do dispositivo, como
mostrado nos exemplos a seguir.
Implementar o repositório de dados
Para implementar um repositório de dados personalizado, crie uma classe que estenda
PreferenceDataStore
. O exemplo abaixo cria um repositório de dados que processa
valores de 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. } }
Execute qualquer operação demorada fora da linha de execução principal para evitar o bloqueio da interface
do usuário. Como é possível que o Fragment
ou o Activity
que contém o
repositório de dados sejam destruídos enquanto um valor é mantido, serialize os dados para que você
não perca nenhum valor alterado pelo usuário.
Ativar o repositório de dados
Depois de implementar seu repositório de dados, defina o novo repositório em
onCreatePreferences()
para que objetos Preference
mantenham valores com o
repositório de dados em vez de usar o SharedPreferences
padrão. É possível ativar um
repositório de dados para cada Preference
ou para toda a hierarquia.
Para ativar um armazenamento de dados personalizado para um Preference
específico, chame
setPreferenceDataStore()
no Preference
, conforme mostrado no exemplo a seguir.
Kotlin
val preference: Preference? = findPreference("key") preference?.preferenceDataStore = dataStore
Java
Preference preference = findPreference("key"); if (preference != null) { preference.setPreferenceDataStore(dataStore); }
Para ativar um repositório de dados personalizado para toda a hierarquia, chame
setPreferenceDataStore()
em PreferenceManager
:
Kotlin
val preferenceManager = preferenceManager preferenceManager.preferenceDataStore = dataStore
Java
PreferenceManager preferenceManager = getPreferenceManager(); preferenceManager.setPreferenceDataStore(dataStore);
Um armazenamento de dados definido para um Preference
específico substitui qualquer repositório de dados
definido para a hierarquia correspondente. Na maioria dos casos, você define um armazenamento de dados para
toda a hierarquia.