Share
Embed
Transcript
18 slides
-
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 -
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() } } -
Nom de la partie - No Error handling mechanism -
No Type Safety - Blocks UI Thread - Inconsistent data in the app -
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 -
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") -
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] ?: "" ) } -
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 -
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" -
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/ -
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) } -
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() } } -
override fun getUserFromProtoStore(): Flow<User> = userProtoDataStore.data.map { user -> User(
firstName = user.firstName, lastName = user.lastName ) } -
Nom de la partie val dataStore = context.createDataStore( name =
USER_PREFERENCES_NAME, migrations = listOf(SharedPreferencesMigration(context, USER_PREFERENCES_NAME )) ) SharedPreferences Migration