Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

com.google.gson.JsonIOException: Abstract classes can't be instantiated! Register an InstanceCreator or a TypeAdapter for this type

Application crash when I try to insert list of Songs into Playlist class.I am using new Android studio version Flamingo and type coverters for converting list of model class. This is my Converter class,I have added type converters to my Database Class.

class DataConverters {

    @TypeConverter
    fun toSongList(string: String): List<Song> {
        val listType = object : TypeToken<List<Song>>() {}.type
        return Gson().fromJson(string, listType) //here crash
    }

    @TypeConverter
    fun fromSongList(list: List<Song>): String {
        return Gson().toJson(list) 
    }

}

This is my Song model class

@Entity(tableName = "song")
data class Song(
    val displayName:String,
    val artist:String,
    val data:String,
    val duration:Int,
    val title:String,
    val album: String,
    val uri: Uri,
    val artUri: String,
    val dateAdded: String,
    @PrimaryKey val id:Long
){
    fun doesMatchSearchQuery(query: String): Boolean {
        val matchingCombinations = listOf(
            displayName
        )

        return matchingCombinations.any {
            it.contains(query, ignoreCase = true)
        }
    }
}

This is my Playlist class.

@Entity(tableName = "playlist")
data class Playlist(
    @PrimaryKey val playlistName: String,
    val songCount: Int,
    val playlistDuration: Long,
    val songs: List<Song>,
)

I have tried to add some proguard rules and it didnt help me.

like image 243
android_d Avatar asked Jan 25 '26 14:01

android_d


2 Answers

In my case, I had to insert these properties into proguard-rules.pro

# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * extends com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# Prevent R8 from leaving Data object members always null
-keepclasseswithmembers class * {
    <init>(...);
    @com.google.gson.annotations.SerializedName <fields>;
}
# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken
like image 179
AllanRibas Avatar answered Jan 27 '26 04:01

AllanRibas


I think the error comes from the val uri: Uri since Gson doesn't know how to Deserialize the Uri.

You should register an adapter for this type

class UriJsonAdapter: JsonSerializer<Uri>, JsonDeserializer<Uri> {
    override fun serialize(src: Uri, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
        return JsonPrimitive(src.toString())
    }
    
    override fun deserialize(src: JsonElement, srcType: Type, context: JsonDeserializationContext): Uri {
        return try {
            val url = src.asString
            if (url.isNullOrEmpty()) {
                Uri.EMPTY
            } else {
                Uri.parse(url)
            }
        } catch (e: UnsupportedOperationException) {
            Uri.EMPTY
        }
    }
}

GsonBuilder().registerTypeAdapter(Uri::class.java, UriJsonAdapter())
like image 25
Tan174 Avatar answered Jan 27 '26 04:01

Tan174



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!