Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JsonIOException: Interfaces can't be instantiated! Register an InstanceCreator or a TypeAdapter for this type. Interface name: retrofit2.Call

I am making a post-call with username and password parameters. The actual call is working and the HTTP response is successful but the following error is being returned.

Error

com.google.gson.JsonIOException: Interfaces can't be instantiated! Register an InstanceCreator or a TypeAdapter for this type. Interface name: retrofit2.Call
    W/System.err:     at com.google.gson.internal.ConstructorConstructor$3.construct(ConstructorConstructor.java:136)
    W/System.err:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$FieldReflectionAdapter.createAccumulator(ReflectiveTypeAdapterFactory.java:427)
    W/System.err:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:383)
    W/System.err:     at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:40)
    W/System.err:     at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27)
    W/System.err:     at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:243)
    W/System.err:     at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:153)
    W/System.err:     at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)

Service

    @FormUrlEncoded
    @POST("login")
    suspend fun authenticateUser(@Field("email") email: String, @Field("password") password: String): Call<LoginResponse>
like image 632
onStackOverflowListener Avatar asked Oct 24 '25 08:10

onStackOverflowListener


1 Answers

TL;DR:

Replace Call with Response

Details

You are here mixing suspend-style and Call-based usages of Retrofit:

  • If you want benefit from using a suspend method (hint: you do), the return type of authenticateUser should be Response<LoginResponse> not Call<LoginResponse>:
    @FormUrlEncoded
    @POST("login")
    suspend fun authenticateUser(@Field("email") email: String, @Field("password") password: String): Response<LoginResponse>
  • If you want to use Retrofit's Call, you should make it not suspendable and use Call::enqueue (for asynchronous call) or Call::execute (for synchronous call):
    @FormUrlEncoded
    @POST("login")
    fun authenticateUser(@Field("email") email: String, @Field("password") password: String): Call<LoginResponse>
    
    ...
    // Somewhere

    //This
    val loginResponse = authenticateUser("email", "password).execute() // throws IOException upon problem talking to the server

    // Or this
    authenticateUser("email", "password).enqueue(object:Callback<LoginResponse>{
        override fun onResponse(call: Call<LoginResponse>, response: Response<LoginResponse>) {
            // It worked!
        }

        override fun onFailure(call: Call<LoginResponse>, t: Throwable) {
            // Something went wrong
        }
    })

See

  • Retrofit's version 2.6.0 changelog (introduces suspend support)
  • Retrofit's webpage
  • Retrofit's javadoc
like image 72
EnzoMolion Avatar answered Oct 27 '25 00:10

EnzoMolion