如何使用改造和 kotlin 从函数中 return 响应 body?

How to return response body from function with retrofit and kotlin?

这是我的代码:

fun getRandomComputerDetails(context: Context) {
    if (isNetworkAvailable(context)) {
        val retrofit: Retrofit = Retrofit.Builder()
            .baseUrl(BuildConfig.API_BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        val service: RandomComputerApiService =
            retrofit.create(RandomComputerApiService::class.java)

        val listCall: Call<RandomComputerApiResponse> = service.getRandomComputer()

        listCall.enqueue(object : Callback<RandomComputerApiResponse> {
            override fun onResponse(
                call: Call<RandomComputerApiResponse>,
                response: Response<RandomComputerApiResponse>
            ) {
                if (response.isSuccessful) {
                    val randomComputerList: RandomComputerApiResponse? = response.body()
                    if (randomComputerList != null) {
                        // TODO how to return randomComputerList?
                    }
                    Log.i("Response result", "$randomComputerList")
                } else {
                    when (response.code()) {
                        400 -> {
                            errorDialogHandler(context, R.string.dialog_error_400)
                            Log.e("Error 400", "Bad Connection")
                        }
                        404 -> {
                            errorDialogHandler(context, R.string.dialog_error_404)
                            Log.e("Error 404", "Not Found")
                        }
                        500 -> {
                            errorDialogHandler(context, R.string.dialog_error_500)
                            Log.e("Error 500", "Server Error")
                        }
                        else -> {
                            errorDialogHandler(context, R.string.dialog_error_generic_error)
                            Log.e("Error", "Generic Error")
                        }
                    }
                }
            }

            override fun onFailure(call: Call<RandomComputerApiResponse>, t: Throwable) {
                Log.e("Response error", t.message.toString())
            }
        })
    } else {
        // NO INTERNET CONNECTION
        errorDialogHandler(context, R.string.dialog_error_no_internet_connection)
    }
}

我如何 return 我的 randomComputerList body 才能在 Fragment 中使用它?我正在使用 retrofit2,我的想法是在特定文件中分离负责执行 API 调用逻辑的函数,然后稍后在片段中调用它。

您可以创建接口并通过它 return 结果例如我创建了一个 ResultListener 接口

interface ResultListener<S> {
    fun onSuccess(successModel: S)
    fun onFail(any: String?)
    fun onError(e: Throwable?)
}

并传递接口并在 response.isSuccessful

上使用 resultListener.onSuccess(randomComputerList) 从接口获取结果
fun getRandomComputerDetails(context: Context, resultListener: ResultListener<RandomComputerApiResponse>) {
    if (isNetworkAvailable(context)) {
        val retrofit: Retrofit = Retrofit.Builder()
            .baseUrl(BuildConfig.API_BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        val service: RandomComputerApiService =
            retrofit.create(RandomComputerApiService::class.java)

        val listCall: Call<RandomComputerApiResponse> = service.getRandomComputer()

        listCall.enqueue(object : Callback<RandomComputerApiResponse> {
            override fun onResponse(
                call: Call<RandomComputerApiResponse>,
                response: Response<RandomComputerApiResponse>
            ) {
                if (response.isSuccessful) {
                    val randomComputerList: RandomComputerApiResponse? = response.body()
                    if (randomComputerList != null) {
                        // TODO how to return randomComputerList?
                        resultListener.onSuccess(randomComputerList)
                    }
                    Log.i("Response result", "$randomComputerList")
                } else {
                    when (response.code()) {
                        400 -> {
                            errorDialogHandler(context, R.string.dialog_error_400)
                            Log.e("Error 400", "Bad Connection")
                        }
                        404 -> {
                            errorDialogHandler(context, R.string.dialog_error_404)
                            Log.e("Error 404", "Not Found")
                        }
                        500 -> {
                            errorDialogHandler(context, R.string.dialog_error_500)
                            Log.e("Error 500", "Server Error")
                        }
                        else -> {
                            errorDialogHandler(context, R.string.dialog_error_generic_error)
                            Log.e("Error", "Generic Error")
                        }
                    }
                }
            }

            override fun onFailure(call: Call<RandomComputerApiResponse>, t: Throwable) {
                Log.e("Response error", t.message.toString())
            }
        })
    } else {
        // NO INTERNET CONNECTION
        errorDialogHandler(context, R.string.dialog_error_no_internet_connection)
    }
}

说这很有趣

getRandomComputerDetails(
    context = this,
    resultListener = object : ResultListener<RandomComputerApiResponse> {
        override fun onSuccess(successModel: RandomComputerApiResponse) {
            //handle success result
        }

        override fun onFail(any: String?) {
            //handle Fail result
        }

        override fun onError(e: Throwable?) {
            //handle Error
        }
    })

回调接口的替代方法是使用协程。为此,将其标记为暂停函数并使用 await() 而不是 enqueue()await() 调用必须包含在 try/catch 中以捕获失败条件(类似于 enqueue() 中的 onFailure)。我将无网络条件移到了开头,这样您就不必将所有代码嵌套在 if 块中。

suspend fun getRandomComputerDetails(context: Context): RandomComputerApiResponse? {
    if (!isNetworkAvailable(context)) {
        // NO INTERNET CONNECTION
        errorDialogHandler(context, R.string.dialog_error_no_internet_connection)
        return null
    }
    val retrofit: Retrofit = Retrofit.Builder()
        .baseUrl(BuildConfig.API_BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build()

    val service: RandomComputerApiService =
        retrofit.create(RandomComputerApiService::class.java)

    val response = try { 
        service.getRandomComputer().await() 
    } catch (t: Throwable) {
        // code for failure condition
        // errorDialogHandler(context, R.string.???)
        Log.e("Response error", t.message.toString())
        return null
    }

    if (response.isSuccessful) {
        return response.body()
    }

    when (response.code()) {
        400 -> {
            errorDialogHandler(context, R.string.dialog_error_400)
            Log.e("Error 400", "Bad Connection")
        }
        404 -> {
            errorDialogHandler(context, R.string.dialog_error_404)
            Log.e("Error 404", "Not Found")
        }
        500 -> {
            errorDialogHandler(context, R.string.dialog_error_500)
            Log.e("Error 500", "Server Error")
        }
        else -> {
            errorDialogHandler(context, R.string.dialog_error_generic_error)
            Log.e("Error", "Generic Error")
        }
    }
    return null
}

然后在您的片段中:

lifecycleScope.launch {
    val response = getRandomComputerDetails(requireContext())
    if (response != null) {
        // Do something with response of type RandomComputerApiResponse
    }
}