另一种异常情况:java.lang.IllegalArgumentException:未找到 Retrofit 注释。 ApiService.login 中的(参数 #2)

Another case with Exception: java.lang.IllegalArgumentException: No Retrofit annotation found. (parameter #2) in ApiService.login

我卡在标题中出现的异常。我检查了类似的主题,但它们是不适用于我的情况的特定案例。您可以在下面看到我的模型、改装设置及其用法。我尝试删除 Body Class、响应 Class,只是为了检查它们是否是罪魁祸首,但不幸的是事实并非如此。也许有人能够找出我做错了什么?

堆栈跟踪:

java.lang.IllegalArgumentException: No Retrofit annotation found. (parameter #2)
        for method ApiService.login
        at retrofit2.Utils.methodError(Utils.java:52)
        at retrofit2.Utils.methodError(Utils.java:42)
        at retrofit2.Utils.parameterError(Utils.java:61)
        at retrofit2.RequestFactory$Builder.parseParameter(RequestFactory.java:311)
        at retrofit2.RequestFactory$Builder.build(RequestFactory.java:182)
        at retrofit2.RequestFactory.parseAnnotations(RequestFactory.java:65)
        at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:25)
        at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:168)
        at retrofit2.Retrofit.invoke(Retrofit.java:147)
        at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
        at $Proxy1.login(Unknown Source)
        at com.rudearts.cyber2020.services.NetworkService$login.invokeSuspend(NetworkService.kt:17)
        at com.rudearts.cyber2020.services.NetworkService$login.invoke(Unknown Source:10)
        at kotlinx.coroutines.flow.SafeFlow.collect(Builders.kt:56)
        at kotlinx.coroutines.flow.internal.ChannelFlowOperatorImpl.flowCollect(ChannelFlow.kt:144)
        at kotlinx.coroutines.flow.internal.ChannelFlowOperator.collectTo$suspendImpl(ChannelFlow.kt:111)
        at kotlinx.coroutines.flow.internal.ChannelFlowOperator.collectTo(Unknown Source:0)
        at kotlinx.coroutines.flow.internal.ChannelFlow$collectToFun.invokeSuspend(ChannelFlow.kt:33)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)

型号:

import com.google.gson.annotations.SerializedName

data class LoginRequest(
    @SerializedName("pin")  val pin:String,
    @SerializedName("pushId") val pushId:String)
import com.google.gson.annotations.SerializedName

data class UserJson (

    @SerializedName("id") val id:Long,
    @SerializedName("name") val name:String?,
    @SerializedName("access_rights") val accessRights:String?)

改造生成器

import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

object RetrofitBuilder {

    private const val BASE_URL = "<url>"

    private val client = OkHttpClient.Builder().build()

    private fun getRetrofit(): Retrofit {
        return Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build()
    }

    val apiService: ApiService = getRetrofit().create(ApiService::class.java)
}
import com.rudearts.cyber2020.model.LoginRequest
import com.rudearts.cyber2020.model.UserJson
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.Headers
import retrofit2.http.POST

interface ApiService {

    @Headers("Content-Type: application/json")
    @POST("login.php")
    suspend fun login(@Body request: LoginRequest):Response<UserJson>

}

其他用法class:

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import java.util.*

class NetworkService {

    private val repoService by lazy { RepoService.instance }
    private val apiService = RetrofitBuilder.apiService

    fun login(pin:String, token:String): Flow<NetworkResult<Boolean>> = flow {
        emit(Loading)
        try {
            val userJson = apiService.login(LoginRequest(pin,token)).body()
            userJson?.let {
                val user =
                    User(userJson.id, userJson.name ?: "", emptyList(), userJson.accessRights ?: "")
                repoService.user = user
            }

            emit(NetworkSuccess(userJson != null))
        } catch (throwable: Throwable) {
            emit(NetworkError(throwable))
        }
    }
}

尝试像这样调用函数

fun login(LoginRequest(pin,token))

而不是这个

fun login(pin:String, token:String)

异常说错误在第二个参数上

可能是因为您使用的是旧版本的 okhttp / retrofit,因为您正在使用挂起功能,它需要两个库的最新版本。