ardevd
ardevd

Reputation: 3407

Android DataStore: Calling Context.createDataStore from Java

I'm trying to implement the new typed DataStore API in Java and I'm having some issues. All the documentation seems to be in Kotlin only and trying to create a new data store is not as straight forward from the Java side it seems.

Calling DataStoreFactoryKt.createDataStore() from Java requires me to provide all the arguments including the ones with default values in the Kotlin implementation. There doesnt seem to be any @JvmOverloads annotation for that function, resulting in my predicament.

fun <T> Context.createDataStore(
    fileName: String,
    serializer: Serializer<T>,
    corruptionHandler: ReplaceFileCorruptionHandler<T>? = null,
    migrations: List<DataMigration<T>> = listOf(),
    scope: CoroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
): DataStore<T> =
    DataStoreFactory.create(
        produceFile = { File(this.filesDir, "datastore/$fileName") },
        serializer = serializer,
        corruptionHandler = corruptionHandler,
        migrations = migrations,
        scope = scope
)

What's the better way around this, if there is any? Or is the Data Store api simple designed to be used with Kotlin only? I have no idea how I would go about providing a CoroutineScope argument from Java.

Upvotes: 10

Views: 13387

Answers (4)

4shutosh
4shutosh

Reputation: 56

This is only valid for dependency version 1.0.0-alpha08 and above

@Ercan approach is correct but requires context every time we need access to the dataStore.

Below is a better approach for the same.

private val Context._dataStore: DataStore<Preferences> by preferencesDataStore(APP_PREFERENCES)

private val dataStore : DataStore<Preferences> = context._dataStore

companion object {
    const val APP_PREFERENCES = "app_preferences"
}

reference: https://issuetracker.google.com/issues/173726702

Upvotes: 3

bigmeco
bigmeco

Reputation: 174

If you need to use proto dataStore from version 1.0.0-beta01, you can:

implementation("androidx.datastore:datastore-core:1.0.0-beta01")

initialize with Data Store Factory

      val data: DataStore<SomeMessage> = DataStoreFactory.create(
        serializer = SessionSerializer, // your Serializer
        corruptionHandler = null,
        migrations = emptyList(),
        scope = CoroutineScope(Dispatchers.IO + Job())

And continue as before

      data.updateData {
            it.toBuilder().setAddress("address").build()
        }

      data.collect { ChargingSession ->
                ChargingSession.address
        }

Upvotes: 2

Ercan
Ercan

Reputation: 2821

After updating dataStore dependency to '1.0.0-alpha08' as below.

// DataStore
implementation "androidx.datastore:datastore-preferences:1.0.0-alpha08"

You can have preferences implementation as follow:

private val Context.dataStore by preferencesDataStore("app_preferences")

After that if you like create some preference key:

private object Keys {
    val HIDE_VISITED = booleanPreferencesKey("hide_visited")
}

other options can be stringPreferencesKey, intPreferencesKey, etc.

Saving value example:

context.dataStore.edit { prefs -> prefs[Keys.HIDE_VISITED] = hideVisited }

Reading saved value example:

val hideVisited = preferences[Keys.HIDE_VISITED] ?: false

Upvotes: 14

V&#237;ctor Albertos
V&#237;ctor Albertos

Reputation: 8303

You need to add to your Grade build file the dependency for DataStore preferences:

implementation "androidx.datastore:datastore-preferences:1.0.0-alpha04"

and not the one for Types, that way you will be able to resolve the androidx.datastore.preferences.Context.createDataStore method that you are expecting:

public fun Context.createDataStore(
    name: String,
    corruptionHandler: ReplaceFileCorruptionHandler<Preferences>? = null,
    migrations: List<DataMigration<Preferences>> = listOf(),
    scope: CoroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
): DataStore<Preferences> =
    PreferenceDataStoreFactory.create(
        corruptionHandler = corruptionHandler,
        migrations = migrations,
        scope = scope
    ) {
        File(this.filesDir, "datastore/$name.preferences_pb")
    }

Upvotes: 2

Related Questions