Как сохранить список <T>в SharedPreferences с использованием делегатов в Kotlin - PullRequest
0 голосов
/ 14 февраля 2020

У меня есть класс PreferenceManager, который хранит и получает данные из локального файла общих настроек с использованием делегатов:

class PreferenceManager constructor(context: Context) {

    private val preferences = context.applicationContext.getSharedPreferences("preferences", Context.MODE_PRIVATE)

    var contacts by FieldDelegate.CustomList<Contact>("recentContacts", listOf())

    private sealed class FieldDelegate<T>(protected val key: kotlin.String, protected val defaultValue: T) :
        ReadWriteProperty<PreferenceManager, T> {


        class CustomList<T>(key: kotlin.String, defaultValue: List<T> = listOf()) : FieldDelegate<List<T>>(key, defaultValue) {
            override fun getValue(thisRef: PreferenceManager, property: KProperty<*>): List<T> {
                val contactList = thisRef.preferences.getString(key, defaultValue.toString())
                return fromJson(contactList)
            }

            override fun setValue(thisRef: PreferenceManager, property: KProperty<*>, value: List<T>) {
                thisRef.preferences.edit().putString(key, Gson().toJson(value)).apply()
            }

            private inline fun <reified T> fromJson(json: kotlin.String?): T =
                Gson().fromJson(json, object : TypeToken<T>() {}.type)
        }

    }

}

Я хочу иметь возможность хранить списки объектов.

Если я использую: preferenceManager.contacts.forEach{Log.d("",it.name}, я получаю

java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to com....common.network.Contact

Я предполагаю, что хотя я использовал встроенную функцию с параметром reified generi c, когда дело доходит до использования этого метода, фактический тип T уже потерян из-за стирания типа

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...