Data save in DataStore in android

Mehedi Hassan Piash
2 min readApr 1, 2021

A new and improved data storage solution aimed at replacing SharedPreferences. Built on Kotlin coroutines and Flow

Why we should use DataStore instead of SharedPreferences

Let’s coding step by step

  1. Add gradle dependency in you build.gradle file
// data store
def dataStoreVersion = "1.0.0-alpha08"
implementation "androidx.datastore:datastore-core:$dataStoreVersion"
implementation "androidx.datastore:datastore-preferences:$dataStoreVersion"
implementation 'com.google.code.gson:gson:2.8.6'

2. Make a DataStore manager for access all necessary functionality for our use case

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 com.google.gson.Gson
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map


class DataStoreManager(var context: Context) {
// Create the dataStore and give it a name same as shared preferences
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore("user_pref")
val dataStore: DataStore<Preferences> = context.dataStore

// Create some keys we will use them to store and retrieve the data
companion object {
val USER_NAME_KEY = stringPreferencesKey("USER_NAME")
val USER_AGE_KEY = intPreferencesKey("USER_AGE")
}

// Store user data
// refer to the data store and using edit


// store data as object
suspend fun <T> storeObjectData(key: Preferences.Key<String>, value: T) {
dataStore.edit { preferences ->
preferences[key] = serializeData(value)
}
}

// save primitives data
suspend fun storeStringData(key: Preferences.Key<String>, value: String) {
dataStore.edit { preferences ->
preferences[key] = value
}
}

suspend fun storeIntData(key: Preferences.Key<Int>, value: Int) {
dataStore.edit { preferences ->
preferences[key] = value
}
}

suspend fun storeDoubleData(key: Preferences.Key<Double>, value: Double) {
dataStore.edit { preferences ->
preferences[key] = value
}
}

suspend fun storeDoubleData(key: Preferences.Key<Float>, value: Float) {
dataStore.edit { preferences ->
preferences[key] = value
}
}

suspend fun storeLongData(key: Preferences.Key<Long>, value: Long) {
dataStore.edit { preferences ->
preferences[key] = value
}
}

suspend fun storeBooleanData(key: Preferences.Key<Boolean>, value: Boolean) {
dataStore.edit { preferences ->
preferences[key] = value
}
}

// Create a flow to retrieve data from the preferences
// flow comes from the kotlin coroutine

// get data as object
inline fun <reified T> getObjectData(key: Preferences.Key<String>): Flow<T> =
dataStore.data.map {
deSerializeData(it[key] ?: "")
}

// get primitives data
fun getStringData(key: Preferences.Key<String>): Flow<String> = dataStore.data.map {
it
[key] ?: ""
}

fun getIntData(key: Preferences.Key<Int>): Flow<Int> = dataStore.data.map {
it
[key] ?: 0
}

fun getDoubleData(key: Preferences.Key<Double>): Flow<Double> = dataStore.data.map {
it
[key] ?: 0.0
}

fun getFloatData(key: Preferences.Key<Float>): Flow<Float> = dataStore.data.map {
it
[key] ?: 0.0f
}

fun getLongData(key: Preferences.Key<Long>): Flow<Long> = dataStore.data.map {
it
[key] ?: 0
}

fun getBooleanData(key: Preferences.Key<Boolean>): Flow<Boolean> = dataStore.data.map {
it
[key] ?: false
}


private fun <T> serializeData(data: T): String {
return Gson().toJson(data)
}

inline fun <reified T> deSerializeData(data: String): T {
return Gson().fromJson(data, T::class.java)
}
}

3. Lets use it inside coroutine

binding.dataStore.setOnClickListener {
lifecycleScope.launch {
userDataStore.storeObjectData(DataStoreManager.USER_NAME_KEY, Geo("1.2", "1.3"))

userDataStore.getObjectData<Geo>(DataStoreManager.USER_NAME_KEY).asLiveData().observe(viewLifecycleOwner,{
Timber.e("serialize : $it")
})
}
}

Ref: https://piashcse.blogspot.com/2021/04/data-save-in-datastore-in-android.html

--

--

Mehedi Hassan Piash

Senior Software Engineer @Field Nation | Android | Kotlin | Compose | Kmp | React-Native