Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Jetpack DataStore

Jetpack DataStore

Ac5b39a4b12e8ca2d6e25b9e7cc142ae?s=128

Divya Jain

April 25, 2022
Tweet

More Decks by Divya Jain

Other Decks in Programming

Transcript

  1. Jetpack DataStore Modern Data Storage Solution Divya Jain divyajain2405

  2. SharedPreferences 1

  3. Nom de la partie - Persist Key-value pairs of Simple

    data - Single Instance of the class, shared by all clients - Easy methods to read-write from Shared preferences - Special editor to make modifications - Read/write operations are on the main thread
  4. override fun getUser(): User { val firstName = sharedPref.getString(PREF_FIRST_NAME, "")

    val lastName = sharedPref.getString(PREF_LAST_NAME, "") return User(firstName = firstName ?: "", lastName = lastName ?: "") } override fun saveUser(user: User) { with (sharedPref.edit()) { putString(PREF_FIRST_NAME, user.firstName) putString(PREF_LAST_NAME, user.lastName) apply() } }
  5. Nom de la partie - No Error handling mechanism -

    No Type Safety - Blocks UI Thread - Inconsistent data in the app
  6. Jetpack DataStore 1

  7. Nom de la partie - Data storage solution - Store

    Key-value pairs or Typed objects - Uses coroutines/flows to store data asynchronously - Uses protocol buffers to store data - Transactional, consistent data operations - Two different implementations Preferences DataStore Proto DataStore
  8. Nom de la partie Preferences DataStore - Modern replacement for

    SharedPreference API - Key-Value pairs to store data, no type safety - No predefined schéma implementation "androidx.datastore:datastore-preferences:1.0.0-beta01" private val Context.userPreferencesDataStore:DataStore<Preferences> by preferencesDataStore(name = "user")
  9. private val USER_FIRST_NAME = stringPreferencesKey("user_first_name") private val USER_LAST_NAME = stringPreferencesKey("user_last_name")

    override suspend fun saveUserToPreferencesStore(user: User) { userPreferencesDataStore.edit { preferences -> preferences[USER_FIRST_NAME] = user.firstName preferences[USER_LAST_NAME] = user.lastName } } override fun getUserFromPreferencesStore(): Flow<User> = userPreferencesDataStore.data .map { preferences -> User( firstName = preferences[USER_FIRST_NAME] ?: "", lastName = preferences[USER_LAST_NAME] ?: "" ) }
  10. Nom de la partie Why preference Datastore over SharedPreferences -

    Safe Asynchronous call over Dispatchers.IO - No apply/commit to save changes - Transactional updates - Exposes data through a Flow - Solid error handling support/no random runtime exceptions
  11. Nom de la partie Proto DataStore - Store and access

    custom typed objects - Predefined Schema in .protoc file - Out of the box type safety - Uses protocol buffers as serialization mechanism implementation "androidx.datastore:datastore:1.0.0-beta01"
  12. syntax = "proto3"; option java_package = "com.djain.protodatastoresample"; option java_multiple_files =

    true; message UserPreference { string first_name = 1; string last_name = 2; } .proto file - app/src/main/proto/
  13. object UserSerializer : Serializer<UserPreference> { override val defaultValue: UserPreference =

    UserPreference.getDefaultInstance() override suspend fun readFrom(input: InputStream): UserPreference { try { return UserPreference.parseFrom(input) } catch (exception: InvalidProtocolBufferException) { throw CorruptionException("Cannot read proto.", exception) } } override suspend fun writeTo(t: UserPreference, output: OutputStream) = t.writeTo(output) }
  14. private val Context.userProtoDataStore: DataStore<UserPreference> by dataStore( fileName = "user.pb", serializer

    = UserSerializer ) override suspend fun saveUserToProtoStore(user: User) { userProtoDataStore.updateData { currentUserData -> currentUserData.toBuilder() .setFirstName(user.firstName) .setLastName(user.lastName) .build() } }
  15. override fun getUserFromProtoStore(): Flow<User> = userProtoDataStore.data.map { user -> User(

    firstName = user.firstName, lastName = user.lastName ) }
  16. Nom de la partie val dataStore = context.createDataStore( name =

    USER_PREFERENCES_NAME, migrations = listOf(SharedPreferencesMigration(context, USER_PREFERENCES_NAME )) ) SharedPreferences Migration
  17. Nom de la partie

  18. THANK YOU Divya Jain divyajain2405 divyajain2405@gmail.com