Usar valores salvos Parte do Android Jetpack.
Este tópico 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, uma Preference
usa SharedPreferences
para salvar valores. A API SharedPreferences
permite a leitura e a gravação
de pares de chave-valor simples a partir de um arquivo que é salvo nas sessões do aplicativo.
A Biblioteca Preference usa uma instância privada 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 esse interruptor para o estado On
, o arquivo SharedPreferences
é atualizado com um par de chave-valor de "notifications" : "true"
. A
chave usada é a mesma que a definida para a Preference
.
Para saber mais sobre a API SharedPreferences
, consulte
Salvar dados 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
app exige que um usuário faça login, convém manter as configurações do
aplicativo na nuvem para que elas sejam refletidas em outros dispositivos
e plataformas. Da mesma forma, se o app tiver opções de configuração específicas
do dispositivo, cada usuário no dispositivo terá configurações separadas, fazendo com que
SharedPreferences
não seja uma solução ideal.
Um PreferenceDataStore
permite que você use um back-end de armazenamento personalizado para manter valores de Preference
. Para
saber mais, consulte Como usar um armazenamento de dados personalizado.
Como ler valores de preferência
Para recuperar o objeto SharedPreferences
que está sendo usado, chame
PreferenceManager.getDefaultSharedPreferences()
.
Esse método funciona em qualquer lugar do seu app. Por exemplo, considerando
EditTextPreference
com uma chave de "assinatura":
<EditTextPreference app:key="signature" app:title="Your signature"/>
O valor salvo para essa Preference
pode ser recuperado 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 abaixo mostra as diferenças entre essas duas interfaces:
OnPreferenceChangeListener | OnSharedPreferenceChangeListener |
---|---|
Definida com base em preferências | Aplicada a todas as preferências |
Chamada quando uma preferência está prestes a mudar o valor salvo. Inclui se o valor pendente é o mesmo que o valor salvo no momento. | Chamada somente quando o valor salvo para uma preferência muda. |
Chamada somente pela biblioteca Preference. Uma parte separada do aplicativo pode mudar o valor salvo. | Chamada sempre que o valor salvo muda, mesmo que seja de uma parte separada do app. |
Chamada antes de o valor pendente ser salvo. | Chamada depois que o valor já foi salvo. |
Chamada ao usar SharedPreferences ou PreferenceDataStore . |
Chamada somente ao usar SharedPreferences . |
OnPreferenceChangeListener
A implementação de um OnPreferenceChangeListener
permite detectar quando o
valor de uma Preference
está prestes a mudar. A partir daí, você pode validar se essa
mudança precisa mesmo ocorrer. Por exemplo, o código abaixo mostra como detectar uma
mudança no valor de uma EditTextPreference
com uma chave de "nome":
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()
,
conforme mostrado a seguir.
Kotlin
preference.onPreferenceChangeListener = ...
Java
preference.setOnPreferenceChangeListener(...);
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 pela sua Preference
mudam,
por exemplo, ao sincronizar as configurações com um servidor. O exemplo abaixo mostra
como detectar quando o valor de uma EditTextPreference
com uma chave de "nome"
muda.
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, "")); } }
Você também precisa registrar o listener via
registerOnSharedPreferenceChangedListener()
,
conforme mostrado a seguir.
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 a seguir.
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); }
Como usar um armazenamento de dados personalizado
Embora a persistência de objetos de Preference
usando SharedPreferences
seja recomendada,
também é possível usar um armazenamento de dados personalizado. Um armazenamento de dados personalizado pode ser útil quando o
aplicativo mantém valores em um banco de dados ou se os valores são específicos do dispositivo, por
exemplo.
Implementar o armazenamento de dados
Para implementar um armazenamento de dados personalizado, primeiro crie uma classe que estenda
PreferenceDataStore
.
O exemplo abaixo cria um armazenamento de dados que gerencia valores 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 operações demoradas fora linha de execução principal para evitar
o bloqueio da interface do usuário. Como é possível que o armazenamento de dados Fragment
ou
Activity
seja destruído ao manter um valor,
você precisa serializar os dados para não perder nenhum valor alterado pelo usuário.
Ativar o armazenamento de dados
Depois de implementar seu armazenamento de dados, você precisa definir o novo armazenamento de dados em
onCreatePreferences()
para que objetos Preference
mantenham valores com o
armazenamento de dados em vez de usar SharedPreferences
. Um armazenamento de dados pode ser
ativado para cada Preference
ou para toda a hierarquia.
Para ativar um armazenamento de dados personalizado para uma Preference
específica, chame
setPreferenceDataStore()
em Preference
, conforme mostrado no exemplo abaixo:
Kotlin
val preference: Preference? = findPreference("key") preference?.preferenceDataStore = dataStore
Java
Preference preference = findPreference(“key”); if (preference != null) { preference.setPreferenceDataStore(dataStore); }
Para ativar um armazenamento de dados personalizado para toda a hierarquia, chame
setPreferenceDataStore()
no 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 armazenamento de dados
que esteja definido para a hierarquia correspondente. Na maioria dos casos, você precisa definir um
armazenamento de dados para toda a hierarquia.