如何向Retrofit传入Class<T>接口适配不同WebService并解决相关报错
报错原因
错误信息:API declarations must be interfaces.
该报错是Retrofit的内置校验逻辑触发的:Retrofit通过动态代理模式生成API接口的实现类,只支持传入接口类型的Class对象,不支持普通类、抽象类等其他类型。
你的代码存在以下两个问题:
- 泛型
<T>没有约束,编译期无法限制传入的类型必须为接口,容易传入不符合要求的类 - 方法参数传入的是实例
t而非接口的Class对象,如果你误传入接口的实现类实例,取到的t::class.java就是实现类的Class,不符合Retrofit要求
修复方案
优化后的代码实现
class ApiProvider { companion object { // 约束泛型+直接传入Class参数,提前校验类型是否为接口 fun <T> apiProvider(serviceClass: Class<T>): T { require(serviceClass.isInterface) { "Retrofit API 必须声明为接口" } return ApiClient.provideRetrofit()!!.create(serviceClass) } // Kotlin 场景下补充泛型实化方法,调用更简洁 inline fun <reified T> apiProvider(): T { return apiProvider(T::class.java) } } }
调用方式
假设你已经定义了Retrofit API接口:
interface UserService { @GET("/user/profile") suspend fun getProfile(): Response<UserProfile> }
你可以选择任意一种方式调用:
- Kotlin 推荐使用泛型实化方式,无需手动传Class:
val userService = ApiProvider.apiProvider<UserService>() - 兼容Java的调用方式,传入接口的Class对象:
val userService = ApiProvider.apiProvider(UserService::class.java)
注意事项
- 所有Retrofit API声明必须是Kotlin/Java接口,不要手动编写该接口的实现类
- 如果确认传入的是接口仍报该错误,检查混淆配置是否误混淆了API接口的类结构,需要将API接口加入混淆白名单
内容的提问来源于stack exchange,提问作者Vahid Zahedi
相关产品推荐
相关产品推荐

