使用改造执行的同步 API 调用
Synchronous API call using retrofit execute
我正在尝试在 Kotlin android 中进行同步 api 调用,实际上我有一个带有 2 个参数的函数,我需要发出 post 请求并获得一个对它的特定响应,并根据我必须 return true 或 false 的响应。
我已尝试使用 Retrofit2 中的 enqueue() 和 execute(),但 execute() 在 UI 线程上运行。甚至尝试创建一个线程并且 运行 仍然在响应之前执行 return 语句。
private fun check(v1: String, v2: String): Boolean {
val vObj = ValidateObj( v1, v2 )
val boolcheck = false
Thread {
try {
val retrofit = ServiceBuilder.buildService(API::class.java)
val res = retrofit.validate(vObj).execute()
boolcheck = res.code() == 200
} catch (e: Exception) {
boolcheck = false
}
}.start()
return true
}
我看到的大多数答案都是一样的,因为提供的代码不完整/错误,所以似乎对我没有用。
如果可能,请帮助提供示例代码。
(提前致谢。)
您的示例代码的问题在于您的函数 check(p1, p2)
中您启动了一个新的 Thread
。这意味着启动该功能的线程将继续 return true
。您必须添加一种方法来等待调用的执行,然后使用结果继续您的过程。
有多种方法可以实现:
- 有回调
private fun check(v1: String, v2: String, onResult: (Boolean) -> Unit) {
val vObj = ValidateObj( v1, v2 )
Thread {
val result = runCatching {
val retrofit = ServiceBuilder.buildService(API::class.java)
val res = retrofit.validate(vObj).execute()
res.code() == 200
}.getOrDefault(false)
onResult(result) // result will then be on the other thread and you have to switch back if necessary
}.start()
}
//with Coroutine
private fun check(v1: String, v2: String, onResult: (Boolean) -> Unit) {
val vObj = ValidateObj( v1, v2 )
CoroutineScope(Dispatchers.IO).launch {
val result = runCatching {
val retrofit = ServiceBuilder.buildService(API::class.java)
val res = retrofit.validate(vObj).execute()
res.code() == 200
}.getOrDefault(false)
onResult(result) // result will then be on the other thread and you have to switch back if necessary
// e.g. CoroutineScope(Dispatchers.Main).launch{onResult(result)}
}
}
fun logic(){
check(p1, p2){ boolean ->
// continue your logic
}
}
- 使用协程
private suspend fun check(v1: String, v2: String): Boolean =
withContext(Dispatchers.IO){
val vObj = ValidateObj( v1, v2 )
runCatching {
val retrofit = ServiceBuilder.buildService(API::class.java)
val res = retrofit.validate(vObj).execute()
res.code() == 200
}.getOrDefault(false)
}
fun logic{
//use function inside a coroutine, e.g.
CoroutineScope(Dispatchers.Main).launch{
val checkResult = check(p1, p2)
...
}
}
我正在尝试在 Kotlin android 中进行同步 api 调用,实际上我有一个带有 2 个参数的函数,我需要发出 post 请求并获得一个对它的特定响应,并根据我必须 return true 或 false 的响应。
我已尝试使用 Retrofit2 中的 enqueue() 和 execute(),但 execute() 在 UI 线程上运行。甚至尝试创建一个线程并且 运行 仍然在响应之前执行 return 语句。
private fun check(v1: String, v2: String): Boolean {
val vObj = ValidateObj( v1, v2 )
val boolcheck = false
Thread {
try {
val retrofit = ServiceBuilder.buildService(API::class.java)
val res = retrofit.validate(vObj).execute()
boolcheck = res.code() == 200
} catch (e: Exception) {
boolcheck = false
}
}.start()
return true
}
我看到的大多数答案都是一样的,因为提供的代码不完整/错误,所以似乎对我没有用。
如果可能,请帮助提供示例代码。 (提前致谢。)
您的示例代码的问题在于您的函数 check(p1, p2)
中您启动了一个新的 Thread
。这意味着启动该功能的线程将继续 return true
。您必须添加一种方法来等待调用的执行,然后使用结果继续您的过程。
有多种方法可以实现:
- 有回调
private fun check(v1: String, v2: String, onResult: (Boolean) -> Unit) {
val vObj = ValidateObj( v1, v2 )
Thread {
val result = runCatching {
val retrofit = ServiceBuilder.buildService(API::class.java)
val res = retrofit.validate(vObj).execute()
res.code() == 200
}.getOrDefault(false)
onResult(result) // result will then be on the other thread and you have to switch back if necessary
}.start()
}
//with Coroutine
private fun check(v1: String, v2: String, onResult: (Boolean) -> Unit) {
val vObj = ValidateObj( v1, v2 )
CoroutineScope(Dispatchers.IO).launch {
val result = runCatching {
val retrofit = ServiceBuilder.buildService(API::class.java)
val res = retrofit.validate(vObj).execute()
res.code() == 200
}.getOrDefault(false)
onResult(result) // result will then be on the other thread and you have to switch back if necessary
// e.g. CoroutineScope(Dispatchers.Main).launch{onResult(result)}
}
}
fun logic(){
check(p1, p2){ boolean ->
// continue your logic
}
}
- 使用协程
private suspend fun check(v1: String, v2: String): Boolean =
withContext(Dispatchers.IO){
val vObj = ValidateObj( v1, v2 )
runCatching {
val retrofit = ServiceBuilder.buildService(API::class.java)
val res = retrofit.validate(vObj).execute()
res.code() == 200
}.getOrDefault(false)
}
fun logic{
//use function inside a coroutine, e.g.
CoroutineScope(Dispatchers.Main).launch{
val checkResult = check(p1, p2)
...
}
}