我需要做下一个:
getAdvertising()
)getAdvertising()
)我通过这样的回调来做到这一点:
fun getAdvertising(callback: Callback<List<Advertising>>) {
val call = myRestClient.advertising
executeAsync(call, callback)
}
private fun <T> executeAsync(call: Call<T>, callback: Callback<T>) {
val currentApplicationProfileResponse = foService.applicationProfileResponse
if (currentApplicationProfileResponse == null) {
getApplicationProfile(object : DefaultRestClientCallback<ApplicationProfileResponse>() {
override fun onTransportResponse(transportResponse: TransportResponse) {
super.onTransportResponse(transportResponse)
if (transportResponse.isSuccessful) {
//asynchronously
call.enqueue(callback)
} else { // not success
if (callback is DefaultRestClientCallback<*>) {
callback.onTransportResponse(transportResponse)
} else {
callback.onResponse(call, transportResponse.originalResponse as Response<T>?)
}
}
}
})
} else { // appProfile is not null
//asynchronously
call.enqueue(callback)
}
}
很好,工作正常。
但是要很多代码。是否有可能通过Kotlin的协程重新控制Callback?
答案 0 :(得分:2)
private fun getADvertise(onResult: (ArrayList<String>) -> Unit = {}) {
CoroutineScope(Dispatchers.IO).launch {
//Do Request To get Data using retrofit
val result = ArrayList<String>()//result from retrofit
withContext(Dispatchers.Main)
{
onResult(result)
}
}
}
private fun isProfileExist(): Boolean {
//true or false
return true
}
private fun getProfilePicture(id: String, OnResult: (String) -> Unit = {}) {
CoroutineScope(Dispatchers.IO).launch {
//Do Request To get Data using retrofit
val result = "Link"//result from retrofit
withContext(Dispatchers.Main)
{
OnResult(result)
}
}
}
//---------your main function------------------>
public fun execute(onResultMain: (ArrayList<String>) -> Unit = {}) {
val exist = isProfileExist()
if (exist) {
getADvertise(onResultMain)
} else {
getProfilePicture("id") {
getADvertise(onResultMain)
}
}
}
//onResultMain -> call back used to get result when they are ready ;)
答案 1 :(得分:1)
在协同程序中使用call.execute()
(即同步改造请求)内部 suspend
功能。
suspend fun <T> executeAsync(call: Call<T>, callback: Callback<T>) {
try {
if(foService.applicationProfileResponse != null) {
if(T is List<Advertising>) {
val advertisings = call.execute() // synchronous call
}
}
} catch(e : Exception) {
// handle exception
}
}
或者, 添加
.addCallAdapterFactory(CoroutineCallAdapterFactory())
改造制造商并将.await()
与deferred
一起使用
call.await() // call is of type deferred
答案 2 :(得分:0)
您可以使用这种方式
enqueue(object : Callback<T> {
override fun onFailure(call: Call<T>, t: Throwable) {
cont.resumeWithException(t)
}
override fun onResponse(call: Call<T>, response: Response<T>) {
if (response.isSuccessful) {
cont.resume(response.body()!!)
} else {
cont.resumeWithException(ErrorResponse(response.message(), response.code()))
}
}
})
}```
```class ErrorResponse(message: String, code: Int) : Throwable(message )```