avatarRyan W

Summary

The article compares Android's traditional SharedPreferences with the newer Jetpack Preferences Datastore, discussing their setup, usage, and differences, and provides a demonstration app for practical reference.

Abstract

The provided web content delves into the intricacies of Android's SharedPreferences and the Jetpack Preferences Datastore, offering a comprehensive guide on their implementation and usage. SharedPreferences, known for its simplicity and ease of use, has been a staple for storing key-value pairs in Android applications. However, its synchronous operations on the main thread can lead to performance issues. The Jetpack Preferences Datastore emerges as a modern alternative, leveraging Kotlin coroutines for asynchronous data operations, ensuring scalability and resilience to data corruption. The article emphasizes the architectural considerations for integrating these storage solutions into Android applications, advocating for the use of repository patterns and dependency injection for a maintainable codebase. A comparison between the two highlights the trade-offs between simplicity and performance, with SharedPreferences suitable for light use cases and Jetpack Preferences Datastore catering to more complex applications. The author concludes with a practical demonstration app, "FusedUserPreferences," to illustrate the implementation of both systems.

Opinions

  • The author views SharedPreferences as a straightforward solution but cautions against its potential for misuse, which can lead to performance bottlenecks.
  • Jetpack Preferences Datastore is praised for its asynchronous operations and improved scalability, marking it as a superior choice for larger applications.
  • The article suggests that the choice between SharedPreferences and Jetpack Preferences Datastore should be based on the specific needs of the application, balancing simplicity with scalability and modern architecture.
  • The author considers their article a cheat sheet due to the infrequent need to implement preference storage in app projects, indicating a common pattern among developers.
  • A reactive programming style is encouraged when using Jetpack Preferences Datastore, with UI components observing data changes and updating accordingly.
  • The author recommends an AI service as a cost-effective alternative to ChatGPT Plus (GPT-4), highlighting its performance and functionality at a lower price point.

Android SharedPreferences and Jetpack Preferences Datastore

This image was created using an AI image creation program.

This article dives into the traditional SharedPreferences and the more recent Jetpack Preferences Datastore. It provides insights into their setup, usage, and key differences, culminating in a demonstration app that showcases both.

💡 Indeed, this article is my cheat sheet because I normally only have to implement once per app project, and I always forget the implementation afterwards.

Introduction to SharedPreferences and Jetpack Preferences Datastore

SharedPreferences

SharedPreferences has been the go-to solution for storing simple key-value pairs in Android applications for years. Its ease of use and straightforward implementation made it a favourite among developers for small-scale projects.

⚠️ While SharedPreferences is suitable for light and simple use cases, it’s important to note that it operates on the main thread, which can lead to performance issues and potential ANRs (Application Not Responding errors) if misused, especially with large sets of data or frequent access.

Jetpack Preferences Datastore

Enter Jetpack Preferences Datastore, a modern, asynchronous solution to overcome SharedPreferences’ limitations. It offers a more scalable approach to managing user preferences, leveraging Kotlin’s coroutines for non-blocking data operations. Unlike its predecessor, Datastore doesn’t immediately return the result upon data retrieval. Additionally, while Datastore does not directly tell us which key-value pair has changed, the design encourages a more reactive programming style, where UI components observe data changes and update accordingly.

⚠️ One major benefit of Datastore over SharedPreferences is its resilience to data corruption and support for transactional data updates, which ensure data consistency.

Implementing SharedPreferences

Minimal code is required to implement SharedPreferences. One initialises it using the application context and defines a listener to track preference changes.

This approach facilitates straightforward read and write operations through its edit() method, allowing for immediate updates to preferences.

Despite its simplicity, we are cautioned against excessive use, which could lead to performance bottlenecks.

Sample code snippet

The SharedPreferences code snippet provided outlines a basic setup for reading from and writing to SharedPreferences:

In this setup, sharedPref is initialised with a specific preference file name and mode. The OnSharedPreferenceChangeListener listens for changes to the preferences, updating the corresponding Flow or state holder when changes occur.

Reading a preference, such as a string or boolean, is done directly through sharedPref.getString or sharedPref.getBoolean, etc., with a default value for cases where the preference does not exist.

Updating a preference involves using the edit() method, followed by putString, putBoolean, etc., and applying the changes with apply().

The simplicity of SharedPreferences is evident here, with direct, synchronous access to preferences. However, the need for manual management of preference listeners and potential issues with synchronous operations on the main thread are noteworthy.

Implementing Jetpack Preferences Datastore

Transitioning to Jetpack Preferences Datastore involves a shift towards an asynchronous model, incorporating Kotlin coroutines for data operations.

The setup requires a bit more boilerplate than SharedPreferences, but it’s a small price for the benefits of asynchronous programming and improved scalability.

Dependency

// Preferences DataStore (SharedPreferences like APIs)
dependencies {
    implementation("androidx.datastore:datastore-preferences:1.0.0")

    // optional - RxJava2 support
    implementation("androidx.datastore:datastore-preferences-rxjava2:1.0.0")

    // optional - RxJava3 support
    implementation("androidx.datastore:datastore-preferences-rxjava3:1.0.0")
}

// Alternatively - use the following artifact without an Android dependency.
dependencies {
    implementation("androidx.datastore:datastore-preferences-core:1.0.0")
}

Sample code snippet

This approach involves defining a DataStore<Preferences> within the context, and using Kotlin's coroutines to fetch and observe preference changes asynchronously. The dataStore.data flow emits preference updates, which are collected and used to update the UI or application state accordingly.

Writing to the Datastore is performed within a coroutine context, ensuring the operation does not block the main thread, with edit { } providing a transactional way of updating preferences.

Architectural Considerations

Adopting MVVM and Clean architecture, both SharedPreferences and Jetpack Preferences Datastore can be integrated seamlessly, ensuring a decoupled, testable codebase.

By abstracting data source implementations behind repository patterns and leveraging dependency injection (e.g., Dagger Hilt), applications can maintain a high degree of flexibility and scalability, irrespective of the underlying preference management system.

Comparison and conclusion

  • SharedPreferences offers simplicity and immediacy, which is ideal for small-scale applications or those with minimal preference data. However, its synchronous nature and potential for misuse underscore the need for careful, limited application.
  • Jetpack Preferences Datastore represents a more modern, robust approach, catering to larger, more complex applications requiring asynchronous operations and a reactive programming model. While its setup and usage are slightly more complex, scalability and performance benefits are undeniable.

In summary, the choice between SharedPreferences and Jetpack Preferences Datastore hinges on specific application needs — simplicity and speed versus scalability and modern architecture.

🧑‍💻 For developers seeking a hands-on demonstration, my demo app, FusedUserPreferences, showcases the implementation of both systems and provides a practical reference for integrating user preferences into Android applications.

Android App Development
Android Development
Android
Mobile App Development
Jetpack Datastore
Recommended from ReadMedium