How to persist data in Android using shared preferences

At some point, we may have come across a to-do application that allows users to add a list of to-dos and then displays the list to the users. What if, after a few hours, a user relaunches the application to see his list of to-dos and finds out that the list is empty? It would be disappointing, right? This is where the need for data persistence comes in.

Shared preferences is one of the few methods used in Android development to save and retrieve primitive data types even when an Android application is terminated and relaunched. It saves data with a specific key that is later used to retrieve the data initially stored with it. Once a shared preference object has been instantiated, an XML file is created and the key-value pairs are saved in that file.

Now, let’s dive into how we can create and write to a shared preference file!

1. Use shared preferences to save data

Before we can save data in a shared preference file, we have to instantiate the shared preference object that will point to the file we want to save our preferences in.

A. Instantiate the shared preference object

You can instantiate a shared preference object with the following syntax:

//First method of shared preference instantiation
val sharedPreference1 = getSharedPreferences("Sample", MODE_PRIVATE)
//Second method of shared preference instantiation
val sharedPreference2 = getPreferences(MODE_PRIVATE)

The first is used when you wish to save data in multiple shared preference files. It is also used when you wish to save data in one activity and retrieve the same data in another activity. It takes two parameters; a string that indicates the name of the shared preference file to be created and the mode in which you want your data to be stored (public or private).

The second is used when you just want to save data in one shared preference file in an activity/fragment and retrieve the same data in that same activity/fragment. It takes just one parameter that indicates how you want your data to be stored (same as the second parameter of the first method of instantiation).

B. Save your data to the shared preference file

The edit() method is used to write into a shared preference file. Since a shared preference object saves only primitive data types, you can write to a shared preference file based on the data type with the following methods:

i. putInt()

ii. putString()

iii. putBoolean()

iv. putLong()

v. putFloat()

vi. putStringSet()

Each of these methods takes two parameters:

The key: The name you would use to access your stored data.

The value: The data you wish to store.

//Call the edit function on the shared preference object
val edit = sharedPreference1.edit()
//Save data of type string using the putString method
edit.putString("Insert a name for your key here", "Save your string data here")

The apply() method is used to effect changes. Another way to effect changes after you write to a shared preference file is to call the commit() function. However, this is not recommended as the commit() function carries out its execution in the main thread, which blocks the main thread and leads to UI components being dragged.

//Call the apply function to effect or apply changes
edit.apply()

2. Use shared preferences to retrieve data

After the data is saved, you can access it anywhere in your application through any of the following methods based on the data type:

i. getInt()

ii. getString()

iii. getBoolean()

iv. getLong()

v. getFloat()

vi. getStringSet()

These methods take two parameters each:

The key: The name of the file the data was stored in.

Default value: A default value is taken if the shared preference object is unable to locate data with the provided key.

//Call the getString function to retrieve the string value saved
sharedPreference1.getString("insert key name here", "set a default value here")

Awesome! We now understand what shared preference is and how it is used to persist data.

Below are the code snippets from a project that uses shared preference to persist user input (data type is an integer):

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/page_one_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:text="SAVE DATA USING SHARED PREFERENCE"
android:textColor="@color/black"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/page_one_edit_text_value"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.45"
app:layout_constraintVertical_chainStyle="packed" />
<EditText
android:id="@+id/page_one_edit_text_value"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:hint="Enter a value"
android:importantForAutofill="no"
android:inputType="number"
android:minHeight="48dp"
android:textColor="@color/black"
app:layout_constraintBottom_toTopOf="@+id/save_button"
app:layout_constraintEnd_toEndOf="@+id/page_one_title"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="@+id/page_one_title"
app:layout_constraintTop_toBottomOf="@+id/page_one_title" />
<Button
android:id="@+id/save_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="SAVE VALUE"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/page_one_edit_text_value"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="@+id/page_one_edit_text_value"
app:layout_constraintTop_toBottomOf="@+id/page_one_edit_text_value" />
<TextView
android:id="@+id/retrieved_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:textSize="34sp"
app:layout_constraintEnd_toEndOf="@+id/save_button"
app:layout_constraintStart_toStartOf="@+id/save_button"
app:layout_constraintTop_toBottomOf="@+id/save_button" />
<TextView
android:id="@+id/retrieved_value_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SAVED VALUE"
android:textColor="@color/black"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="@+id/retrieved_value"
app:layout_constraintStart_toStartOf="@+id/retrieved_value"
app:layout_constraintTop_toBottomOf="@+id/retrieved_value" />
</androidx.constraintlayout.widget.ConstraintLayout>
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//Find views by their IDs
val pageOneEditTextValue = findViewById<EditText>(R.id.page_one_edit_text_value)
val retrievedValue = findViewById<TextView>(R.id.retrieved_value)
val saveButton = findViewById<Button>(R.id.save_button)
//Initialize shared preference
val sharedPreference = getSharedPreferences("Sample", MODE_PRIVATE)
//Get value from shared preference
var result = sharedPreference.getString("key", "null")
retrievedValue.text = result
saveButton.setOnClickListener {
//Collect value from user
val value = pageOneEditTextValue.text.toString()
sharedPreference.edit().putString("key", value).apply()
//Get value from shared preference
result = sharedPreference.getString("key", "null")
retrievedValue.text = result
}
}
}

Happy Coding!

Free Resources