如何使用改造和 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
}
}
这是我的代码:
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
}
}