I have a few interfaces that looks something like the following:
interface ApiInterface : Context.Element {
@GET(Urls.url)
suspend fun getSomeData(): Data
}
interface Context.Element {
operator fun plus(context: Context): Context
}
I am trying to implement a Context
implementation in similar way of the Kotlin CoroutineContext
. As I am trying to add my Retrofit http interface as a Context.Element
it ends up inheriting some other functions. The code compiles and runs fine until I call a function from my ApiInterface instance which inherits from Context.Element
therefore doesn't have any @GET
, @POST
or any retrofit annotation.
If I run the following code:
val context = ApiInterfaceImpl()
context + DifferentApiInterfaceImpl()
I receive a Exception in thread "main" java.lang.IllegalArgumentException: HTTP method annotation is required (eg, @GET, @POST, etc.). for method Context.plus
Exception in thread "main" java.lang.IllegalArgumentException: HTTP method annotation is required (eg, @GET, @POST, etc.). for method Context.plus
.
I believe that if I am able to make the Retrofit annotation processor to skip the functions inherited from Context.Element
this problem would be solved. Is there any way to to this? Any @Transient
like annotation for functions? I tried to use @JvmSynthetic
but no luck.
The issue here is not in annotation processor, but in the way Retrofit works. It doesn't generate an implementation class, but creates a proxy object at runtime and this proxy object handles all method calls and routes them to the proper handler. So obviously it can't handle a non-service method. Also it's not clear how you would provide an implementation for that non-annotated method. So I would say it's currently impossible.
Edit: As you are using default method on interface to provide the implementation, it should generally work I believe, because Retrofit
handles default methods separately. The issue here might be that Retrofit
knows about java default methods only and by default kotlin does not use them (for compatibility with java 7 and below). So if you make the compiler generate java default method, it should work. Please check out this post for details.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.