Skip to content

Gson Converter

A Converter which uses Gson for serialization to and from JSON.

Sample usage

Get a hold of SharedPreferences instance to use the extensions put and get:

lateinit var prefs: SharedPreferences
...
prefs = appContext.getSharedPreferences("test", Context.MODE_PRIVATE)

To save and load primitive types:

prefs.put("key", 1)
val a = prefs.get("key", Int::class, 1)

To save and load object types:

val list = mutableListOf<Int>()
prefs.put("key", list)
list = prefs.get("key", object : TypeToken<List<Int>>() {}, mutableListOf()))

When not using primitive types you should use TypeToken instead of T::class, for example:

    @Test
    fun getObjectWithType() {
        val list = ArrayList<MyObjectType>().apply { this.add(MyObjectType("string", 1, true)) }

        prefs.put("key", list)
        assertEquals(list, prefs.get("key", object : TypeToken<List<MyObjectType>>() {}, ArrayList()))
        assertNotEquals(list, prefs.get("key", List::class, ArrayList<MyObjectType>()))
    }

    @Test
    fun getObjectWithType2() {
        val list = ArrayList<Int>().apply { this.add(1) }

        prefs.put("key", list)
        assertEquals(list, prefs.get("key", object : TypeToken<List<Int>>() {}, ArrayList()))
        assertNotEquals(list, prefs.get("key", List::class, ArrayList<Int>()))
    }

    @Parcelize data class MyObjectType(val fieldA: String, val fieldB: Int, val fieldC: Boolean) : Parcelable
Both tests will ran to completion.

Regarding assertNotEquals(list, prefs.get("key", List::class, ArrayList<Int>())) being true, it’s related with the fact that public <T> T fromJson(JsonReader reader, Type typeOfT){} method from Gson.java (line 886) is type unsafe\:
“Since Type is not parameterized by T, this method is type unsafe and should be used carefully”.
That’s why I believe I’m getting List<Double> instead of List<Integer>.

Also:

prefs.put(prefs, "key", 1)
prefs.get(prefs, "key", Boolean::class, false)
Will throw JsonParseException.