I have tiny wrapper around SharedPreferences written in Kotlin. I use Gson for setting and getting not primitive types. Now I would like to migrate this class to work with Moshi, but I do not understand how to work with generics in Moshi.
package com.example.extensions
import android.content.Context
import android.content.SharedPreferences
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
object Preferences {
lateinit var preferences: SharedPreferences
val json = GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create()!!
fun init(context: Context) {
preferences = context.getSharedPreferences(
context.packageName + ".preferences",
Context.MODE_PRIVATE
)
}
inline fun <reified T> get(key: String, defaultValue: T? = null): T? {
return when (T::class) {
String::class -> preferences.getString(key, defaultValue as? String) as T?
Int::class -> preferences.getInt(key, defaultValue as? Int ?: -1) as T?
Boolean::class -> preferences.getBoolean(key, defaultValue as? Boolean ?: false) as T?
Float::class -> preferences.getFloat(key, defaultValue as? Float ?: -1f) as T?
Long::class -> preferences.getLong(key, defaultValue as? Long ?: -1) as T?
else -> {
val value = preferences.getString(key, null)
if (value == null)
defaultValue else
json.fromJson<T>(value, object: TypeToken<T>(){}.type)
}
}
}
fun <T> set(key: String, value: T) {
when (value) {
is String? -> edit { putString(key, value) }
is Int -> edit { putInt(key, value) }
is Boolean -> edit { putBoolean(key, value) }
is Float -> edit { putFloat(key, value) }
is Long -> edit { putLong(key, value) }
else -> edit { putString(key, json.toJson(value)) }
}
}
private fun edit(operation: SharedPreferences.Editor.() -> Unit) {
val editor = preferences.edit()
operation(editor)
editor.apply()
}
fun reset(): Boolean {
return preferences.edit().clear().commit()
}
}
I tried this, but I'm getting an error:
package com.mezhevikin.converter.extensions
import android.content.Context
import android.content.SharedPreferences
import com.squareup.moshi.Moshi
object Preferences {
lateinit var preferences: SharedPreferences
val moshi: Moshi = Moshi.Builder().build()
fun init(context: Context) {
preferences = context.getSharedPreferences(
context.packageName + ".preferences",
Context.MODE_PRIVATE
)
}
inline fun <reified T> get(key: String, defaultValue: T? = null): T? {
return when (T::class) {
String::class -> preferences.getString(key, defaultValue as? String) as T?
Int::class -> preferences.getInt(key, defaultValue as? Int ?: -1) as T?
Boolean::class -> preferences.getBoolean(key, defaultValue as? Boolean ?: false) as T?
Float::class -> preferences.getFloat(key, defaultValue as? Float ?: -1f) as T?
Long::class -> preferences.getLong(key, defaultValue as? Long ?: -1) as T?
else -> {
val value = preferences.getString(key, null)
if (value == null)
defaultValue else
moshi.adapter(T::class.java).fromJson(value)
}
}
}
fun <T: Any> set(key: String, value: T?) {
when (value) {
is String? -> edit { putString(key, value) }
is Int -> edit { putInt(key, value) }
is Boolean -> edit { putBoolean(key, value) }
is Float -> edit { putFloat(key, value) }
is Long -> edit { putLong(key, value) }
else -> edit { putString(key, moshi.adapter(value!!.javaClass).toJson(value)) }
}
}
private fun edit(operation: SharedPreferences.Editor.() -> Unit) {
val editor = preferences.edit()
operation(editor)
editor.apply()
}
fun reset(): Boolean {
return preferences.edit().clear().commit()
}
}
Error: Caused by: java.lang.IllegalArgumentException: Expected at least one @ToJson or @FromJson method on java.lang.Class