有什么方法可以 "hide" 来自 Retrofit 注释处理器的 Kotlin 函数吗?
Is there any way to "hide" a Kotlin function from Retrofit annotation processor?
我有几个界面如下所示:
interface ApiInterface : Context.Element {
@GET(Urls.url)
suspend fun getSomeData(): Data
}
interface Context.Element {
operator fun plus(context: Context): Context
}
我正在尝试以与 Kotlin CoroutineContext
类似的方式实现 Context
实现。当我尝试将我的 Retrofit http 接口添加为 Context.Element
时,它最终继承了一些其他功能。代码编译并且 运行 很好,直到我从我的 ApiInterface 实例调用一个函数,该实例继承自 Context.Element
因此没有任何 @GET
、@POST
或任何改造注释。
如果我运行下面的代码:
val context = ApiInterfaceImpl()
context + DifferentApiInterfaceImpl()
我收到了 Exception in thread "main" java.lang.IllegalArgumentException: HTTP method annotation is required (e.g., @GET, @POST, etc.). for method Context.plus
.
我相信,如果我能够让 Retrofit 注释处理器跳过从 Context.Element
继承的功能,这个问题就会得到解决。有什么办法吗?任何 @Transient
之类的功能注释?我尝试使用 @JvmSynthetic
但没有成功。
这里的问题不在于注解处理器,而在于 Retrofit 的工作方式。它不生成实现 class,而是在运行时创建一个 proxy object,此代理对象处理所有方法调用并将它们路由到适当的处理程序。所以很明显它不能处理非服务方法。此外,还不清楚您将如何为该非注释方法提供实现。
所以我会说这目前是不可能的。
编辑:
当您在接口上使用默认方法来提供实现时,我相信它通常应该可以工作,因为 Retrofit
单独处理默认方法。这里的问题可能是 Retrofit
只知道 java 默认方法,默认情况下 kotlin 不使用它们(为了与 java 7 及以下版本兼容)。因此,如果您让编译器生成 java 默认方法,它应该可以工作。请查看 this post 了解详情。
我有几个界面如下所示:
interface ApiInterface : Context.Element {
@GET(Urls.url)
suspend fun getSomeData(): Data
}
interface Context.Element {
operator fun plus(context: Context): Context
}
我正在尝试以与 Kotlin CoroutineContext
类似的方式实现 Context
实现。当我尝试将我的 Retrofit http 接口添加为 Context.Element
时,它最终继承了一些其他功能。代码编译并且 运行 很好,直到我从我的 ApiInterface 实例调用一个函数,该实例继承自 Context.Element
因此没有任何 @GET
、@POST
或任何改造注释。
如果我运行下面的代码:
val context = ApiInterfaceImpl()
context + DifferentApiInterfaceImpl()
我收到了 Exception in thread "main" java.lang.IllegalArgumentException: HTTP method annotation is required (e.g., @GET, @POST, etc.). for method Context.plus
.
我相信,如果我能够让 Retrofit 注释处理器跳过从 Context.Element
继承的功能,这个问题就会得到解决。有什么办法吗?任何 @Transient
之类的功能注释?我尝试使用 @JvmSynthetic
但没有成功。
这里的问题不在于注解处理器,而在于 Retrofit 的工作方式。它不生成实现 class,而是在运行时创建一个 proxy object,此代理对象处理所有方法调用并将它们路由到适当的处理程序。所以很明显它不能处理非服务方法。此外,还不清楚您将如何为该非注释方法提供实现。 所以我会说这目前是不可能的。
编辑:
当您在接口上使用默认方法来提供实现时,我相信它通常应该可以工作,因为 Retrofit
单独处理默认方法。这里的问题可能是 Retrofit
只知道 java 默认方法,默认情况下 kotlin 不使用它们(为了与 java 7 及以下版本兼容)。因此,如果您让编译器生成 java 默认方法,它应该可以工作。请查看 this post 了解详情。