DataStore para Kotlin: guia completo com exemplos práticos
1. O que é e para que serve
DataStore é uma biblioteca do Google para armazenar pequenos volumes de dados em aplicações Kotlin (e Android). Ela substitui a obsoleta SharedPreferences e oferece uma forma mais segura, assíncrona e type-safe de trabalhar com dados. O DataStore utiliza Kotlin Coroutines e Flow, tornando-se a escolha ideal para aplicações modernas que usam programação reativa.
Para que serve o DataStore? O principal problema do SharedPreferences é a leitura síncrona do disco, que pode bloquear a thread da UI, além da falta de suporte a tipos de dados (tudo é armazenado como Set<String>). O DataStore resolve esses problemas: todas as operações de leitura e escrita são assíncronas, e os dados são armazenados em objetos tipados (via Protocol Buffers ou Preferences). Além disso, o DataStore lida automaticamente com erros de serialização e fornece uma API limpa para manipulação de dados.
A biblioteca existe em duas variações: Preferences DataStore (para armazenar pares simples de chave-valor, como no SharedPreferences) e Proto DataStore (para armazenar objetos tipados via Protocol Buffers). Neste artigo, focaremos no Preferences DataStore, por ser o mais simples e usado.
2. Instalação
O DataStore é distribuído via Maven Central. Para adicioná-lo ao seu projeto Kotlin/Android, inclua a dependência no arquivo build.gradle.kts (módulo app):
dependencies {
// Preferences DataStore
implementation("androidx.datastore:datastore-preferences:1.1.1")
// Se você estiver usando Proto DataStore
// implementation("androidx.datastore:datastore-core:1.1.1")
// Para suporte a Coroutines (geralmente já está no projeto)
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0")
}
Se você usa Gradle com Groovy (build.gradle), a linha ficará assim:
implementation 'androidx.datastore:datastore-preferences:1.1.1'
Após sincronizar o Gradle, a biblioteca estará pronta para uso.
3. Início rápido — exemplo mínimo funcional
Vamos criar um DataStore simples para armazenar o nome do usuário e um contador.
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
// Extensão para Context, criando o DataStore
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "user_settings")
// Chaves para os dados
val USER_NAME_KEY = stringPreferencesKey("user_name")
val COUNTER_KEY = intPreferencesKey("counter")
class UserPreferences(private val context: Context) {
// Leitura do nome do usuário como Flow
val userName: Flow<String?> = context.dataStore.data.map { preferences ->
preferences[USER_NAME_KEY]
}
// Leitura do contador como Flow
val counter: Flow<Int> = context.dataStore.data.map { preferences ->
preferences[COUNTER_KEY] ?: 0
}
// Salvando o nome do usuário
suspend fun saveUserName(name: String) {
context.dataStore.edit { preferences ->
preferences[USER_NAME_KEY] = name
}
}
// Incrementando o contador
suspend fun incrementCounter() {
context.dataStore.edit { preferences ->
val currentCounter = preferences[COUNTER_KEY] ?: 0
preferences[COUNTER_KEY] = currentCounter + 1
}
}
Também na biblioteca
Trabalho com imagens em PHP: redimensionamento e corte (resize, crop)
Trabalhando com Excel em TypeScript: bibliotecas, ferramentas e exemplos de código
Geração de Relatórios PDF em C# (.NET) com iTextSharp e QuestPDF
Trabalhando com Markdown em C# (.NET): bibliotecas e exemplos
Cheerio para JavaScript (Node.js): guia completo com exemplos