Chapter 7: Data Persistence and Storage

Data Persistence and Storage! This is where your app stops being “amnesiac” — it starts remembering things even after the user closes it, kills the process, or restarts the phone. We’re talking about saving user preferences (like dark mode toggle, username), app settings, or even structured data like a list of favorite tips from our calculator.

In January 2026, Google has made it crystal clear: SharedPreferences is legacy for simple cases, but Jetpack DataStore is the modern, recommended way for key-value storage. Room remains king for structured, relational data (like a real database).

We’ll cover:

  • SharedPreferences (quick legacy overview — still works, but avoid new use)
  • DataStore (Preferences DataStore for simple key-value, Proto DataStore for typed objects)
  • Room basics (entities, DAOs, database)
  • Hands-on: Save/retrieve user data in our Tip Calculator (e.g., save default tip %, last bill amount)

Let’s do this like we’re sitting together debugging on your laptop in Airoli — detailed explanations, code snippets, why-things, common pitfalls, and a full example.

1. SharedPreferences (Quick Legacy Overview – Why It’s Fading in 2026)

SharedPreferences is the old-school XML-based key-value store. It’s simple, but has big issues:

  • Synchronous I/O → Can block main thread → ANRs/jank
  • No type safety → Everything as String/Int/Boolean
  • No transactions → Partial writes possible on crash
  • Not reactive → Manual polling to observe changes

Still used in many legacy apps, but Google docs now say: “Use DataStore instead for new projects.”

Quick example (don’t use for new code, but good to know):

Kotlin

In 2026: EncryptedSharedPreferences is deprecated too (replaced by DataStore + Tink for secure needs). Avoid for new apps.

2. Jetpack DataStore (The Modern Replacement – Use This!)

DataStore comes in two flavors:

  • Preferences DataStore → Simple key-value (like SharedPreferences but async, Flow-based, type-safe)
  • Proto DataStore → Structured, typed data (like a mini-Protobuf schema)

Why DataStore wins in 2026:

  • Fully asynchronous (Coroutines + Flow)
  • Reactive: UI auto-updates via collectAsState()
  • Type-safe & transactional
  • Coroutine-safe, no main-thread blocks
  • Migration from SharedPreferences easy

Add dependency (app/build.gradle.kts – latest stable ~1.2.0, alpha 1.3.0-alpha04 as of Jan 14, 2026):

Kotlin

Preferences DataStore Example (simple key-value):

Create a object for easy access:

Kotlin

Usage in ViewModel or Composable:

Kotlin

In Composable (observe & update):

Kotlin

How to get DataStore instance (best: Hilt or manual):

Kotlin

Proto DataStore (for complex objects – e.g., UserProfile):

  1. Define proto schema (src/main/proto/user.proto):
proto
  1. Generate classes (build → gradle sync)
  2. Create DataStore:
Kotlin

Then read/write with map, updateData.

For beginners: Start with Preferences DataStore — it’s simpler and covers 80% of cases.

3. Room Database Basics (For Structured Data)

Room = SQLite abstraction. Use when you need queries, relationships, large data.

Core parts:

  • Entity → Table (data class with @Entity)
  • DAO → Interface with queries (@Dao)
  • Database → Abstract class with @Database

Add dependencies (latest stable Room 2.8.4 as of Nov 2025 – still current in Jan 2026):

Kotlin

Example: Save favorite tips history

  1. Entity:
Kotlin
  1. DAO:
Kotlin
  1. Database:
Kotlin
  1. Usage in ViewModel:
Kotlin

Observe in Composable: val tips by viewModel.recentTips.collectAsStateWithLifecycle(initialValue = emptyList())

4. Hands-on: Save and Retrieve User Data in Tip Calculator

Let’s integrate Preferences DataStore (save default tip % and last bill) + Room (save calculation history).

Steps:

  1. Add DataStore & Room dependencies.
  2. Create Preferences DataStore for defaults.
  3. Create Room for history.
  4. Update TipViewModel to load/save.
  5. Show history list in a new screen or bottom of calculator.

Quick Integration Snippet (in your TipViewModel):

Kotlin

In HomeScreen:

  • Load last bill into TextField on start.
  • After calculate → call viewModel.saveCalculation(…)
  • Add a LazyColumn to show recent tips from Room.

This makes your app remember user prefs across sessions!

You’ve now got persistence! Play with it: Add delete history button, search tips, or encrypt sensitive data later.

Questions? Want to add migration from SharedPrefs? Proto DataStore example? Or Hilt injection for DataStore/Room? Tell me — next chapter: Networking & APIs (fetch real data). You’re building a proper app now — super proud of you! Keep going! 🚀💾

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *