In many Android apps, users expect the app to remember their last action even after it is closed and reopened. In this post, we will implement Shared Preferences in an MVVM architecture and use the Singleton pattern to make sure our data source is initialized only once.
The final result is simple. When the app restarts, the last suggested drink is automatically shown to the user.
![]() |
| Closing the app from the background |
![]() |
| After reopening the drink is already selected |
Watch the Video Tutorial
If you prefer a step-by-step walkthrough, watch the video tutorial below:
What We Are Building
We already have an MVVM setup where the Repository is responsible for providing data. At the moment, the data comes from a mock data source. Our goal is to add another data source that stores data permanently using Shared Preferences in Java. For Kotlin only syntax will change core logic will be the same.
Whenever a new drink is suggested, we will save it. When the app starts again, we will read that value and show it to the user.
Why We Use the Singleton Pattern
The Singleton pattern ensures that a class has only one instance throughout the app lifecycle. This is important for Shared Preferences because we want a single, consistent access point.
By using Singleton, every part of the app reads and writes data from the same Shared Preferences instance.
Step 1 Create SharedPreferences Data Source
The first step is to create a new class called SharedPreferencesDataSource. This class will handle all Shared Preferences operations and will be implemented as a Singleton.
public class SharedPreferencesDataSource {
static SharedPreferencesDataSource instance;
private SharedPreferences sharedPreferences;
private SharedPreferences.Editor editor;
public static SharedPreferencesDataSource getInstance() {
if (instance == null)
instance = new SharedPreferencesDataSource();
return instance;
}
}
Initializing Shared Preferences
Next, we declare SharedPreferences and its Editor. These will be initialized using a context.
public class SharedPreferencesDataSource {
static SharedPreferencesDataSource instance;
private SharedPreferences sharedPreferences;
private SharedPreferences.Editor editor;
public static SharedPreferencesDataSource getInstance() {
if (instance == null)
instance = new SharedPreferencesDataSource();
return instance;
}
public void init(Context context) {
sharedPreferences = context.getSharedPreferences("drinkSuggesterPrefs", Context.MODE_PRIVATE);
editor = sharedPreferences.edit();
}
}
This init method will be called only once when the application starts.
Saving the Suggested Drink
When a drink is suggested, we store it as a string in Shared Preferences.
public void setSuggestedDrink(String drinkName) {
editor.putString("last_suggested_drink", drinkName);
editor.commit();
}
Retrieving the Last Suggested Drink
To restore the data, we create a method that reads the value from Shared Preferences.
public String getLastSuggestedDrink() {
String drinkName = sharedPreferences.getString("last_suggested_drink", null);
return drinkName;
}
Initializing the Data Source in Application Class
The best place to initialize Shared Preferences is inside the Application class. This ensures it is ready before any screen is shown.
import android.app.Application;
public class DrinkSuggesterApp extends Application {
@Override
public void onCreate() {
super.onCreate();
SharedPreferencesDataSource.getInstance().init(getApplicationContext());
}
}
Updating the Repository
The Repository is responsible for providing data to the ViewModel. We update it to read and write data using SharedPreferencesDataSource.
public String lastSuggestedDrink() {
return SharedPreferencesDataSource.getInstance().getLastSuggestedDrink();
}
private void setLastSuggestedDrink(String drinkName) {
SharedPreferencesDataSource.getInstance().setSuggestedDrink(drinkName);
}
Restoring Data in ViewModel
When the ViewModel is created, we immediately ask the Repository for the last saved drink.
If the value exists, we update the UI using LiveData.
String lastSuggestedDrink = mMainRepository.lastSuggestedDrink();
if (lastSuggestedDrink != null) {
mDrinksMutableData.postValue(lastSuggestedDrink);
}
Final Result
When the app runs for the first time, no drink is shown. After a drink is suggested, it is saved in Shared Preferences. When the app is closed and reopened, the last suggested drink appears automatically.
Conclusion
By combining Shared Preferences, MVVM, and the Singleton pattern, we achieve clean data persistence without breaking architecture rules. This approach keeps the app modular, scalable, and easy to maintain.
If you enjoyed this tutorial, consider subscribing to Coding Reel for more Android development content.





No comments:
Post a Comment
Share your thoughts ...