Data Persistence in Android – SharedPreferences, SQLite, and Room Database - Textnotes

Data Persistence in Android – SharedPreferences, SQLite, and Room Database


Learn how to store data persistently in Android using SharedPreferences, SQLite, and Room Database. Understand the use cases for each method and how to implement them effectively.

Data Persistence in Android

Data persistence is crucial for Android applications that need to save user preferences, app settings, or even larger amounts of data locally. In this tutorial, we will explore three main ways to persist data in Android:

  1. SharedPreferences – For saving small key-value pairs such as user settings.
  2. SQLite – For working with structured data in a relational format.
  3. Room Database – A modern, abstraction layer over SQLite that simplifies database operations.

i) Using SharedPreferences for Small Data Storage

SharedPreferences is a simple key-value pair storage system in Android that is mainly used for storing small amounts of data, such as user preferences or app settings. It allows data to be saved as key-value pairs and is persisted across app restarts.

How to Use SharedPreferences

  1. Saving Data:

To save data in SharedPreferences, you use an instance of the SharedPreferences.Editor class to put data (such as strings, booleans, etc.) and then commit or apply the changes.


SharedPreferences sharedPreferences = getSharedPreferences("MyPrefs", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("username", "JohnDoe");
editor.putBoolean("isLoggedIn", true);
editor.apply(); // apply() is asynchronous, commit() is synchronous
  1. Retrieving Data:

To retrieve data, simply call the get methods from SharedPreferences, specifying the key and default value if the key does not exist.


SharedPreferences sharedPreferences = getSharedPreferences("MyPrefs", MODE_PRIVATE);
String username = sharedPreferences.getString("username", "defaultUser");
boolean isLoggedIn = sharedPreferences.getBoolean("isLoggedIn", false);
  1. Removing Data:

You can remove specific key-value pairs using remove() or clear all stored data with clear().


SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove("username");
editor.apply();

ii) Working with SQLite for Local Databases

SQLite is a powerful relational database that comes pre-installed in Android devices. It is ideal for storing larger datasets in a structured format using tables, rows, and columns. Although SQLite provides flexibility, developers often need to work with raw SQL queries, which can be complex.

How to Use SQLite

  1. Creating a Database:

To use SQLite, you'll typically extend the SQLiteOpenHelper class. This class helps you manage database creation, versioning, and upgrades.


public class MyDatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "MyDatabase";
public static final String TABLE_NAME = "users";
public static final String COL_1 = "ID";
public static final String COL_2 = "USERNAME";

public MyDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}

@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + "(ID INTEGER PRIMARY KEY AUTOINCREMENT, USERNAME TEXT)");
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
  1. Inserting Data:

To insert data into the database, you'll use the insert() method of the SQLiteDatabase class.


SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("USERNAME", "JohnDoe");
long result = db.insert("users", null, contentValues);

if (result == -1) {
Log.e("SQLite", "Insert failed");
} else {
Log.i("SQLite", "Data inserted");
}
  1. Querying Data:

To retrieve data, you can use query() or rawQuery(). Here's an example of using rawQuery() to fetch data:


SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM users WHERE USERNAME = ?", new String[] {"JohnDoe"});

if (cursor != null) {
cursor.moveToFirst();
String username = cursor.getString(cursor.getColumnIndex("USERNAME"));
cursor.close();
}
  1. Updating and Deleting Data:

You can update or delete records using update() and delete() methods.


ContentValues contentValues = new ContentValues();
contentValues.put("USERNAME", "JaneDoe");
int rowsUpdated = db.update("users", contentValues, "ID = ?", new String[] {"1"});

int rowsDeleted = db.delete("users", "USERNAME = ?", new String[] {"JohnDoe"});

iii) Using Room Database as a Modern Abstraction Layer over SQLite

Room Database is a modern, higher-level abstraction over SQLite that makes database operations easier by providing a clean API and avoiding the need for writing raw SQL queries. It integrates with the Lifecycle library, making it easier to work with persistent data in a more efficient and readable way.

How to Use Room Database

  1. Setting Up Room:

First, add dependencies to your build.gradle file:


implementation "androidx.room:room-runtime:2.4.0"
annotationProcessor "androidx.room:room-compiler:2.4.0"
  1. Create an Entity:

In Room, an Entity is a class that represents a table in the database. Each field in the class corresponds to a column in the table.


@Entity(tableName = "users")
public class User {
@PrimaryKey(autoGenerate = true)
private int id;
private String username;

// Constructor, getters, and setters
}
  1. Create a DAO (Data Access Object):

A DAO is an interface that defines methods for accessing the database. It abstracts the database operations, allowing you to perform CRUD operations.


@Dao
public interface UserDao {
@Insert
void insert(User user);

@Query("SELECT * FROM users WHERE username = :username")
User getUserByUsername(String username);

@Delete
void delete(User user);
}
  1. Create the Database:

The database class extends RoomDatabase and provides an instance of the database.


@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract UserDao userDao();
}
  1. Using Room Database:

To use Room, you get an instance of the database and call DAO methods to interact with the database.


AppDatabase db = Room.databaseBuilder(getApplicationContext(),
AppDatabase.class, "user-database").build();

UserDao userDao = db.userDao();
User user = new User("JohnDoe");
userDao.insert(user);

User fetchedUser = userDao.getUserByUsername("JohnDoe");

Conclusion

In this tutorial, you’ve learned how to persist data in Android using SharedPreferences, SQLite, and Room Database. SharedPreferences is great for small key-value pairs, SQLite provides a relational database for complex data, and Room Database simplifies SQLite interactions with a higher-level API.

By understanding and implementing these storage solutions, you can make your Android apps more efficient and capable of storing data across app launches.