Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
💾 Data, Network & Architecture  ·  Lesson 29

SharedPreferences & DataStore

What to store here

Use key–value storage for small settings: user name, dark mode on/off, "onboarding seen", last selected tab. For lists of records (notes, products) use a database (Room).

9:41▮▮ 85%←Settings⋮ProfileYour name: RiyaSAVEDark modeReminder notificationsDelete all done notes
Student Diary settings — all saved with SharedPreferences

SharedPreferences basics

Kotlin
val prefs = getSharedPreferences("settings", Context.MODE_PRIVATE)

// write
prefs.edit {                                  // androidx.core.content.edit
    putString("user_name", "Riya")
    putBoolean("dark_mode", true)
    putInt("launch_count", 5)
}

// read (always give a default)
val name = prefs.getString("user_name", "Student")
val dark = prefs.getBoolean("dark_mode", false)
val count = prefs.getInt("launch_count", 0)

// remove / clear
prefs.edit { remove("user_name") }
prefs.edit { clear() }
putStringin memoryapply()background writesettings.xmlapp private foldernext launchgetString → "Riya"
Values survive app restarts

A clean wrapper class

Instead of repeating keys everywhere, the final app wraps preferences in one class with Kotlin properties:

Kotlin – data/SettingsStore.kt
package com.codingeasily.studentdiary.data

import android.content.Context
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.edit

/** Small key-value settings saved with SharedPreferences. */
class SettingsStore(context: Context) {

    private val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)

    var userName: String
        get() = prefs.getString(KEY_NAME, "Student") ?: "Student"
        set(value) = prefs.edit { putString(KEY_NAME, value) }

    var darkMode: Boolean
        get() = prefs.getBoolean(KEY_DARK, false)
        set(value) = prefs.edit { putBoolean(KEY_DARK, value) }

    var remindersEnabled: Boolean
        get() = prefs.getBoolean(KEY_REMINDERS, true)
        set(value) = prefs.edit { putBoolean(KEY_REMINDERS, value) }

    fun applyTheme() {
        AppCompatDelegate.setDefaultNightMode(
            if (darkMode) AppCompatDelegate.MODE_NIGHT_YES else AppCompatDelegate.MODE_NIGHT_NO
        )
    }

    companion object {
        private const val KEY_NAME = "user_name"
        private const val KEY_DARK = "dark_mode"
        private const val KEY_REMINDERS = "reminders"
    }
}
Kotlin – using it
// Student Diary – SettingsFragment
settings = SettingsStore(requireContext())
binding.etName.setText(settings.userName)
binding.btnSaveName.setOnClickListener { settings.userName = binding.etName.text.toString() }

// MainActivity.onResume – show it in the drawer header
header.tvUserName.text = getString(R.string.hello_user, SettingsStore(this).userName)

Example: first launch / onboarding

Kotlin
class SplashActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val prefs = getSharedPreferences("app", MODE_PRIVATE)
        val seen = prefs.getBoolean("onboarding_done", false)
        startActivity(Intent(this, if (seen) MainActivity::class.java else OnboardingActivity::class.java))
        finish()
    }
}

// OnboardingActivity – when the user taps "Get started"
getSharedPreferences("app", MODE_PRIVATE).edit { putBoolean("onboarding_done", true) }

Preferences DataStore

DataStore is the modern replacement: it is asynchronous (never blocks the UI), exposes values as a Flow and handles errors safely.

TOML + Kotlin DSL
// libs.versions.toml
datastore = "1.1.1"
androidx-datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastore" }

// app/build.gradle.kts
implementation(libs.androidx.datastore.preferences)
Kotlin
// One DataStore per file – declared at top level of a Kotlin file
val Context.dataStore by preferencesDataStore(name = "settings")

object Keys {
    val USER_NAME = stringPreferencesKey("user_name")
    val DARK_MODE = booleanPreferencesKey("dark_mode")
}

class SettingsRepository(private val context: Context) {
    // read as a Flow – the UI updates whenever the value changes
    val userName: Flow<String> = context.dataStore.data.map { it[Keys.USER_NAME] ?: "Student" }

    suspend fun setUserName(name: String) {
        context.dataStore.edit { it[Keys.USER_NAME] = name }
    }
}

// Fragment
viewLifecycleOwner.lifecycleScope.launch {
    repo.userName.collect { binding.tvHello.text = "Hello, $it" }
}
binding.btnSave.setOnClickListener {
    viewLifecycleOwner.lifecycleScope.launch { repo.setUserName(binding.etName.text.toString()) }
}

SharedPreferences vs DataStore vs Room

SharedPreferencesDataStoreRoom
DataSmall key–valuesSmall key–valuesTables of records
APISynchronous get, async applyFlow + suspendDAO, Flow, SQL
Main-thread safeMostlyYesYes (with coroutines)
Best forSimple apps, quick flagsNew apps, observed settingsNotes, products, orders

Common mistakes

  • Different file names in different places ("settings" vs "Settings") → values seem lost.
  • Storing big JSON lists in preferences → slow; use Room.
  • Creating two DataStore instances for the same file → crash; declare it once at top level.

Summary

  • getSharedPreferences(name, MODE_PRIVATE) + edit { putX } + getX(key, default).
  • Wrap keys in a class with properties (SettingsStore).
  • DataStore = Flow-based, async alternative for new code.
✅ Practice

Count how many times the app was opened and show "Welcome back! Visit #5" on the home screen. Then rewrite the same feature with DataStore.

Frequently Asked Questions

Where is SharedPreferences data saved?
In an XML file inside the app's private folder (/data/data//shared_prefs/). It is deleted when the app is uninstalled or its data is cleared.
Is it safe to store a password or token?
Do not store passwords. For login tokens, private app storage is usually acceptable for normal apps; for sensitive apps encrypt the value or use the Android Keystore.
apply() or commit()?
apply() saves in the background and returns immediately — use it. commit() blocks until written. The KTX edit { } uses apply() by default.
← Android Tutorial (Kotlin)
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

Next topicRoom Database (SQLite) Your progress: 29 / 43 (67%) · Lesson 30 / 43 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free