Retrofit2 call.enqueue回调类型不匹配IDE报错解决方法
问题:Retrofit回调类型不匹配报错解决方法
我是编程新手,正在开发一款从API获取JSON数据的Android App,使用Retrofit和Gson实现。此前可用的代码现在在Android Studio中报错,已确认导入包无误,报错出现在AppRepository.kt的call.enqueue行,提示类型不匹配,需要Callback<ResponseBody!>!,实际传入的是Callback<JSONModel>。
相关代码片段
1. Retrofit API接口 BookAPI.kt
interface BookAPI { @GET("books?$OTHER_PARAMS") fun getBookDetailsByISBN(@Query("bibkeys") isbn: String ) : Call<ResponseBody> companion object { const val OTHER_PARAMS = ... } }
2. Dagger Hilt注入的Retrofit实例 AppModule.kt
@Module @InstallIn(SingletonComponent::class) object AppModule { @Provides @Singleton fun provideBookAPI(): BookAPI { return Retrofit.Builder() .baseUrl(BookAPI.BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build() .create(BookAPI::class.java) } }
3. 报错的AppRepository.kt代码
//imports related to retrofit import com.fracta7.e_bookshelf.data.local.database.book.Book import com.fracta7.e_bookshelf.data.remote.BookAPI import com.fracta7.e_bookshelf.domain.model.book.JSONModel import retrofit2.Call import retrofit2.Callback import retrofit2.Response import javax.inject.Inject class AppRepository @Inject constructor( private val bookAPI: BookAPI ) { fun getBookByISBN(isbn: String): Book { var remoteInfo: JSONModel? = null val call = bookAPI.getBookDetailsByISBN(isbn) // 报错位置:类型不匹配,需要Callback<ResponseBody!>!,实际传入Callback<JSONModel> call.enqueue(object : Callback<JSONModel> { override fun onResponse(call: Call<JSONModel>, response: Response<JSONModel>) { //on response } override fun onFailure(call: Call<JSONModel>, t: Throwable) { //on failure } }) ... } }
4. build.gradle配置
plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' id 'kotlin-kapt' id 'dagger.hilt.android.plugin' } android {...} dependencies { implementation 'androidx.core:core-ktx:1.8.0' implementation "androidx.compose.ui:ui:$compose_version" implementation 'androidx.compose.material3:material3:1.0.0-beta01' implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' implementation 'androidx.activity:activity-compose:1.5.1' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version" debugImplementation "androidx.compose.ui:ui-tooling:$compose_version" debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version" //Room def room_version = '2.4.3' implementation "androidx.room:room-ktx:$room_version" kapt "androidx.room:room-compiler:$room_version" //dagger hilt implementation 'com.google.dagger:hilt-android:2.43.2' kapt 'com.google.dagger:hilt-android-compiler:2.43.2' kapt 'androidx.hilt:hilt-compiler:1.0.0' implementation 'androidx.hilt:hilt-navigation-compose:1.0.0' //viewmodel implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1' //retrofit implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' //coroutines implementation "androidx.hilt:hilt-navigation-compose:1.0.0" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4" }
解决方法
报错核心原因是API接口定义的返回类型和回调中使用的类型不匹配:BookAPI.getBookDetailsByISBN返回Call<ResponseBody>,但回调用了Callback<JSONModel>,两者类型不一致。
步骤1:修改API接口的返回类型
既然已添加GsonConverterFactory,Retrofit会自动将JSON响应解析为JSONModel对象,直接把接口方法的返回类型改成Call<JSONModel>:
interface BookAPI { @GET("books?$OTHER_PARAMS") fun getBookDetailsByISBN(@Query("bibkeys") isbn: String ) : Call<JSONModel> // 修改此处为JSONModel companion object { const val OTHER_PARAMS = ... } }
步骤2:修正回调类型(可选,接口修改后IDE会自动提示)
确保回调中的Call和Response类型与接口返回一致:
call.enqueue(object : Callback<JSONModel> { override fun onResponse(call: Call<JSONModel>, response: Response<JSONModel>) { if (response.isSuccessful) { remoteInfo = response.body() // 后续处理逻辑 } } override fun onFailure(call: Call<JSONModel>, t: Throwable) { // 处理请求失败逻辑 } })
额外注意:异步请求的同步问题
当前getBookByISBN方法返回Book,但Retrofit的enqueue是异步请求,方法会在请求完成前直接返回,导致remoteInfo始终为null。建议改成挂起函数配合协程处理异步:
// 1. 接口改成挂起函数(Retrofit 2.6+支持) interface BookAPI { @GET("books?$OTHER_PARAMS") suspend fun getBookDetailsByISBN(@Query("bibkeys") isbn: String ) : Response<JSONModel> } // 2. Repository中的方法改成挂起函数 suspend fun getBookByISBN(isbn: String): Book? { return try { val response = bookAPI.getBookDetailsByISBN(isbn) if (response.isSuccessful) { val jsonModel = response.body() // 将JSONModel转换为Book对象返回 jsonModel?.let { convertToBook(it) } } else { null } } catch (e: Exception) { e.printStackTrace() null } } // 3. 补充JSONModel转Book的转换函数示例 private fun convertToBook(jsonModel: JSONModel): Book { return Book( isbn = jsonModel.isbn, title = jsonModel.title, // 其他字段映射... ) }
内容的提问来源于stack exchange,提问作者Javokhir Matnazarov
相关产品推荐
相关产品推荐

