有什么方法可以 "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 了解详情。