使用Retrofit时,我得到了不能调用适配器的错误



我想使用视图模型和实时数据函数的改造库拉加密数据,但我得到以下错误,我将非常感激,如果你能帮助。

建造改造结构的部分:

object RetrofitInstance {
private val retrofit by lazy {
Retrofit.Builder()
.baseUrl ( BASE_URL )
.addConverterFactory ( GsonConverterFactory.create() )
.build()
}
val api: ApiTerminal by lazy {
retrofit.create ( ApiTerminal::class.java )
}
}

本项目接口部分:

interface ApiTerminal {
@GET("currencies/ticker")
suspend fun getPost ( @Query("key") key : String ): Response<ArrayList<CoinModel>>
}

这个项目中的仓库部分:

class Repository {
suspend fun getPost( key : String ) : Response<ArrayList<CoinModel>> {
return RetrofitInstance.api.getPost ( key )
}
}

项目中确定视图模型功能的部分:

class MainViewModel ( private val repository: Repository ) : ViewModel() {
val response = MutableLiveData<Response<ArrayList<CoinModel>>>()
fun getPost ( key : String ) {
viewModelScope.launch {
response.value = repository.getPost ( key )
}
}
}

项目的这一部分是活动区域:

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val viewModelFactory = MainViewModelFactory ( Repository() )
val txt = findViewById<TextView>(R.id.txt)
txt.setOnClickListener {
val viewModel = ViewModelProvider(this, viewModelFactory )[MainViewModel::class.java]
viewModel.getPost("this part contains api key")
viewModel.response.observe(this, Observer {
if (it.isSuccessful) {
txt.text = it.body()?.get(0)?.currency

}
})
}
}
}

我得到的错误:

2022-04-24 22:01:28.638 5834-5834/com.rk.quex E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.rk.quex, PID: 5834
java.lang.IllegalArgumentException: Unable to create call adapter for class java.lang.Object
for method ApiTerminal.getPost
at retrofit2.ServiceMethod$Builder.methodError(ServiceMethod.java:752)
at retrofit2.ServiceMethod$Builder.createCallAdapter(ServiceMethod.java:237)
at retrofit2.ServiceMethod$Builder.build(ServiceMethod.java:162)
at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:170)
at retrofit2.Retrofit$1.invoke(Retrofit.java:147)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy1.getPost(Unknown Source)
at com.rk.quex.repository.Repository.getPost(Repository.kt:11)
at com.rk.quex.MainViewModel$getPost$1.invokeSuspend(MainViewModel.kt:19)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:367)
at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:30)
at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(Cancellable.kt:25)
at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:110)
at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56)
at kotlinx.coroutines.BuildersKt.launch(Unknown Source:1)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47)
at kotlinx.coroutines.BuildersKt.launch$default(Unknown Source:1)
at com.rk.quex.MainViewModel.getPost(MainViewModel.kt:17)
at com.rk.quex.MainActivity.onCreate$lambda-1(MainActivity.kt:24)
at com.rk.quex.MainActivity.$r8$lambda$hFYFqoAo62q-drAqh-AGqF7aib8(Unknown Source:0)
at com.rk.quex.MainActivity$$ExternalSyntheticLambda0.onClick(Unknown Source:6)
at android.view.View.performClick(View.java:7448)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for class java.lang.Object.
Tried:
* retrofit2.ExecutorCallAdapterFactory
at retrofit2.Retrofit.nextCallAdapter(Retrofit.java:241)
at retrofit2.Retrofit.callAdapter(Retrofit.java:205)
at retrofit2.ServiceMethod$Builder.createCallAdapter(ServiceMethod.java:235)
... 32 more

您能试一下吗?

  • 请分享您正在使用的Retrofit版本依赖项。

  • 在IO线程中启动getPost协程:

    viewModelScope.launch (Dispatchers.IO) {//代码}

  • 请尝试解析存储库中的主体,以更接近MVVM原则,理想的情况是创建一个事件响应密封类,能够根据响应动画UI,但我不会混淆你,我会做2个例子,一个没有事件响应,一个有:

class Repository {

suspend fun getPost( key : String ) : ArrayList<CoinModel>? {
val response = RetrofitInstance.api.getPost(key)
return if(response.isSuccessful){
response.body?.let { arrayList ->
arrayList
} ?: run {
null
}
} else {
null
}
}

}

事件响应密封类的示例:

sealed class Result <out T> {
data class Error <T> (val message: Exception?): Result<T>()
data class Success <T> (val data: T): Result<T>()
}
class Repository {
suspend fun getPost(key: String): Result<List<CoinModel>> {
return try {
val response = RetrofitInstance.api.getPost(key)
if (response.isSuccessful){
response.body()?.let { coinModelList ->
return@let Result.Success(coinModelList)
} ?: run {
Result.Error(Exception("The body is empty"))
}
} else {
Result.Error(Exception("Response not successful"))
}
} catch (e: Exception) {
Result.Error(Exception("Network error"))
}
}
}

这是如何从你的viewModel:

class MainViewModel ( private val repository: Repository ) : ViewModel() {
val response = MutableLiveData<List<CoinModel>>()
fun getPost ( key : String ) {
viewModelScope.launch(Dispatchers.IO) {
when(val result = repository.getPost ( key )){
is Result.Error -> //Handle your error logic. You can access the Exception message with result.message
is Result.Success -> response.postValue(result.data)
}
}
}
}

请记住这是我"手写"的。D

最新更新