Хранилище данных Android: вызов Context.createDataStore из Java

#android #kotlin

#Android #kotlin

Вопрос:

Я пытаюсь реализовать новый типизированный API хранилища данных на Java, и у меня возникли некоторые проблемы. Кажется, что вся документация находится только в Kotlin, и попытка создать новое хранилище данных не так проста со стороны Java, как кажется.

Вызов DataStoreFactoryKt.createDataStore() из Java требует от меня предоставления всех аргументов, включая аргументы со значениями по умолчанию в реализации Kotlin. Похоже, для этой функции нет никаких @JvmOverloads аннотаций, что приводит к моему затруднительному положению.

 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
)
 

Какой лучший способ обойти это, если он есть? Или простой API хранилища данных предназначен для использования только с Kotlin? Я понятия не имею, как я мог бы предоставить CoroutineScope аргумент из Java.

Комментарии:

1. Та же проблема возникает на стороне клиента Kotlin, для сериализатора нет значения по умолчанию, но в документах указано, что вы можете создать экземпляр хранилища данных <Настройки>, просто указав имя файла. Я думаю, что здесь что-то не так: (

Ответ №1:

После обновления зависимости хранилища данных до ‘1.0.0-alpha08’, как показано ниже.

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

У вас может быть реализация настроек следующим образом:

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

После этого, если хотите, создайте некоторый ключ предпочтений:

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

другими параметрами могут быть string PreferencesKey, int PreferencesKey и т. Д.

Пример сохранения значения:

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

Чтение примера сохраненного значения:

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

Ответ №2:

Вам необходимо добавить в файл сборки Grade зависимость для настроек хранилища данных:

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

и не для типов, таким образом, вы сможете разрешить androidx.datastore.preferences.Context.createDataStore ожидаемый метод:

 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")
    }
 

Комментарии:

1. Это не решение. Он не может продолжать использовать более старую версию DataStore . Лучшим решением было бы объяснить, как использовать более новые версии.

2. В этом ответе объясняется, что требуется добавить другую зависимость, не указывая ее версию. Я не понимаю, что вы имеете в виду.

Ответ №3:

Если вам нужно использовать хранилище данных proto версии 1.0.0-beta01, вы можете:

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

инициализировать с помощью фабрики хранилища данных

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

И продолжайте, как и раньше

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

      data.collect { ChargingSession ->
                ChargingSession.address
        }
 

Ответ №4:

Это действительно только для версии зависимостей 1.0.0-alpha08 и выше

Подход @Ercan верен, но требует context каждый раз, когда нам нужен доступ к хранилищу данных.

Ниже приведен лучший подход к тому же самому.

 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"
}
 

ссылка: https://issuetracker.google.com/issues/173726702