在Kotlin中回调后返回值 [英] Returning a value after callback in Kotlin
问题描述
如何在kotlin中进行回调后返回值,我尝试使用Thread.sleep但无法正常工作
How can I return a value after a callback in kotlin, I tried using Thread.sleep but it doesn't work
fun searchColorFromAPI(): Colors {
val service: RetrofitService = ServiceGenerator.createService(RetrofitService::class.java)
val result: MutableList<String> = arrayListOf()
val call: Call<Colors?>? = service.unityConverter(result)
call?.enqueue(object : Callback<Colors?> {
override fun onResponse(call: Call<Colors?>?, response: Response<Colors?>) {
//switchProgressVisibility()
if (response.isSuccessful) {
val serviceResponse: Colors? = response.body()
if (serviceResponse != null) {
mColors = serviceResponse
}
else {
//buildToast(getString(R.string.null_response))
}
}
else {
//buildToast(getString(R.string.response_unsuccessful))
val errorBody: ResponseBody = response.errorBody()
Log.e(TAG, errorBody.toString())
}
}
override fun onFailure(call: Call<Colors?>?, t: Throwable?) {
/* buildToast(getString(R.string.error_calling_service))
Log.e(TAG, t?.message)*/
}
})
return mColors
}
总是会在onFailure或onResponse之前返回mColor,因为它们是异步的.在此代码出现在MainActivity中之前,但我被建议起飞,但是现在当我尝试获取mColors时,在执行onResponse之前和之后我会得到一个空值,请我仍在学习Kotlin和Android.
Always, the mColors is returned before the onFailure or onResponse because they're asynchronous. Before this code was in MainActivity but I was advised to take off, but now when I try get mColors I get the empty value before and after the onResponse is executed, please I'm still learning Kotlin and Android.
推荐答案
您的问题源于Retrofit
call
是asynchronous
的事实,因此,只要您调用searchColorFromAPI
,它就会返回mColors
但是API
调用可能尚未进行,因此您可以在API调用之前获得mColors值.
Your problem stems from the fact that Retrofit
call
is asynchronous
, so as soon as you call searchColorFromAPI
it returns you mColors
but the API
call may not have been made yet, so you get the mColors value before API call.
要解决此问题,可以执行
To solve this issue, you can do
-
使用
callback
, 这在您当前的设置中几乎不需要修改,但是第二个选项优于此设置. 使用callback
函数应该看起来像这样.
Use
callback
, this will require little modification in your current setup, but the 2nd option is preferable over this. Usingcallback
your function should look like this.
/* Now instead of returning a value, your function takes a function (named callback)
as parameter. when your api call finishes, you can call the callback function and
pass the api response.
*/
fun searchColorFromAPI(callback: (Colors?) -> Unit) {
val service: RetrofitService = ServiceGenerator.createService(RetrofitService::class.java)
val result: MutableList<String> = arrayListOf()
val call: Call<Colors?>? = service.unityConverter(result)
call?.enqueue(object : Callback<Colors?> {
override fun onResponse(call: Call<Colors?>?, response: Response<Colors?>) {
//switchProgressVisibility()
if (response.isSuccessful) {
val serviceResponse: Colors? = response.body()
/** pass API response to callback */
callback(serviceResponse)
}
else {
val errorBody: ResponseBody = response.errorBody()
Log.e(TAG, errorBody.toString())
callback(null)
}
}
override fun onFailure(call: Call<Colors?>?, t: Throwable?) {
callback(null)
}
})
}
然后在您的activity
中声明一个function
,如下所示.
And in your activity
declare a function
as follows.
// This function will be called when your api call finishes
// and it will give you the api response
fun apiCallback(colors: Colors?){
if(colors == null){
// API Call failed
}
else{
// use colors as returned by API
}
}
现在调用searchColorFromApi
应该看起来像这样
And now call to searchColorFromApi
should look like this
searchColorFromApi(apiCallback)
-
使用实时数据,在
在 viewmodel
中,如果您不使用viewmodel
,则在具有searchColorFromApi
功能的class
中声明它.
Use Live Data, declare following
field
in yourviewmodel
, if you are not usingviewmodel
then declare it in theclass
which hassearchColorFromApi
function.
var colors: MutableLiveData<Colors> = MutableLiveData()
并按如下所示修改您的searchColorFromAPI
函数
and modify your searchColorFromAPI
function as follows
fun searchColorFromAPI() {
val service: RetrofitService = ServiceGenerator.createService(RetrofitService::class.java)
val result: MutableList<String> = arrayListOf()
val call: Call<Colors?>? = service.unityConverter(result)
call?.enqueue(object : Callback<Colors?> {
override fun onResponse(call: Call<Colors?>?, response: Response<Colors?>) {
//switchProgressVisibility()
if (response.isSuccessful) {
val serviceResponse: Colors? = response.body()
if (serviceResponse != null) {
colors.postValue(response.body)
}
}
else {
colors.postValue(null)
val errorBody: ResponseBody = response.errorBody()
Log.e(TAG, errorBody.toString())
}
}
override fun onFailure(call: Call<Colors?>?, t: Throwable?) {
colors.postValue(null)
}
})
}
并在您的activity
中执行以下操作
and in your activity
do following
fun setupObservers(){
yourApiCallingClass.colors.observe(this, Observer {
// this code is called when ever value of color field changes
})
}
这篇关于在Kotlin中回调后返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!