Unable to invoke no-args constructor for retrofit2.Call

Issue

I have the following retrofit singleton:

interface MyAPI
{
    @GET("/data.json")
    suspend fun fetchData() : Call<MyResponse>

    companion object
    {
        private val BASE_URL  "http://10.0.2.2:8080/"

        fun create(): MyAPI
        {
            val gson  GsonBuilder()
                .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
                .create()

            val retrofit  Retrofit.Builder()
                .addConverterFactory( GsonConverterFactory.create( gson ) )
                .baseUrl( BASE_URL )
                .build()

            return retrofit.create( MyAPI::class.java )
        }
    }
}

MyResponse.kt

data class MyResponse(
    val listOfData: List<DataEntity>
)

DataEntity.kt

data class DataEntity(
    @SerializedName("name")
    val fullName: String
}

I call the code from ModelView the following way:

viewModelScope.launch {
    try {
        val webResponse  MyAPI.create().fetchData().await()
        Log.d( tag, webResponse.toString() )
    }
    catch ( e : Exception )
    {
        Log.d( tag, "Exception: " + e.message )
    }
}

But I keep getting:

Unable to invoke no-args constructor for retrofit2.Call<com.host.myproject.net.response.MyResponse>. Registering an InstanceCreator with Gson for this type may fix this problem.

I can’t seem to find a solution for this problem.. Any hints please?

EDIT:

The JSON response:

[
    {
    "name": "A"
    },
    {
    "name": "B"
    },
    {
    "name": "C"
    }
]

Solution

The problem is that you try to combine suspend with a Call<T> return type. When you use suspend you should make the Retrofit function return the data directly, like this:

suspend fun fetchData() : List<DataEntity> // Note: Not MyResponse, see below

Then all you have to do is to remove .await() when you make the call, like this:

// Will throw exception unless HTTP 2xx is returned
val webResponse  MyAPI.create().fetchData()

Note that you should not use the MyResponse class at all since the JSON returns an array directly.

Answered By – Enselic

Leave a Comment