vendredi 25 mars 2022

Retrofit 2 -API declarations must be interfaces

I am trying to abstract the Retrofit complexity to an class named BaseService2 and all the classes that need to consume a webservice need to extend from that class, but i keep getting this error even with me passing an interface to the method retro.create(iWs::class.java), the iWs is an interface.

Test method:

  @Test
fun consultar_pedidos_test() {
    val pedidoService = PedidoService()
    pedidoService.consultarPedidos(205, null) {
        it.message
        it.statusCode
    }

    try {
        Thread.sleep(10 * 1000.toLong())
    } catch (e: InterruptedException) {
        e.printStackTrace()
    }
}

Class that need to consume an webservice:

class PedidoService : BaseService2<IPedidoService>(IPedidoService::class.java) {

fun consultarPedidos(codVendedor: Int, codRede: Int?, handler: (IResponse) -> Unit) =
    execute(handler, (service as IPedidoService).getPedidosCarteira(codVendedor, codRede)) }

Class BaseService 2 that i use to abstract the retrofit complexity:

open class BaseService2<T>(iWs: Class<T>) {

lateinit var handler: (IResponse) -> Unit
lateinit var call: Call<IResponse>
var service: Class<T>

init {
    val retro: Retrofit = Retrofit.Builder()
            .baseUrl("http://10.2.10.43:3000/")
            .addConverterFactory(GsonConverterFactory.create())
            //.client(httpClient.build())
            .build()

    service = retro.create(iWs::class.java)
}

fun execute(handler: (IResponse) -> Unit, call: Call<IResponse>) {
    this.handler = handler
    this.call = call

    call.enqueue(object : Callback<IResponse> {
        override fun onResponse(call: Call<IResponse>, response: Response<IResponse>) {
            val pedido = response.body()
            handler.execute()
        }

        override fun onFailure(call: Call<IResponse>, t: Throwable) {
            Log.i(Constants.TAG.value, "test onFailure")
        }
    })
}

}

Interface with the webservices:

interface IPedidoService {

@GET("pedidos")
fun getPedidosCarteira(
        @Query("codVendedor") codVendedor: Int?,
        @Query("codRede") codRede: Int?): Call<IResponse>

}

Stacktrace:

java.lang.IllegalArgumentException: API declarations must be interfaces.
at retrofit2.Retrofit.validateServiceInterface(Retrofit.java:156)
at retrofit2.Retrofit.create(Retrofit.java:134)
at br.com.mili.isisav.model.service.BaseService2.<init>(BaseService2.kt:23)
at br.com.mili.isisav.model.service.pedidoCarteira.PedidoService.<init>(PedidoService.kt:6)
at br.com.mili.isisav.retrofit.RetrofitTest.consultar_pedidos_test(RetrofitTest.kt:66)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:388)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2205)

Also i accept suggetions on how to make this kind of abstraction on a different/better way, to simplify the use of this library.





Aucun commentaire:

Enregistrer un commentaire