如何让一个方法等到它的改造方法在 return 之前得到响应?
How to make a method wait till its retrofit method got its response before return?
如何让一个函数等到其中的改造方法在 return 之前得到响应?
我在 Stack Overflow 上看到了很多问题和答案,但由于愚蠢或我没有完全理解它们。
我有一个视图模型,它为视图提供要在屏幕上显示的文本。
喜欢,我确实喜欢这个观点,activity_foo.xml:
android:text = "@{fooViewModel.getUserName()}"
并且在视图模型中 class:
fun getUserName() : String = fooRepository.getUserName()
我想你会明白这个策略,因为它在 MVVM 模式中很常见。
所以 FooRepository,我的意思是我的视图模型的真实存储库如下所示:
class MainRepository(private val userApi: UserApi) {
fun getUserList() : ArrayList<User>? {
var userList : ArrayList<User>? = null
userApi.getAllUser().enqueue(object : Callback<ArrayList<User>> {
override fun onResponse(call: Call<ArrayList<User>>, response: Response<ArrayList<User>>) {
if (response.body() != null) {
Log.e("user list succeed", response.body()!!.toString())
userList = response.body()!!
Log.e("user list saved", userList!![0].id)
}
}
override fun onFailure(call: Call<ArrayList<User>>, t: Throwable) {
Log.e("user list fail", t.message!!)
}
})
Log.e("this log", "shouldn't be above the logs in onResponse ")
return userList
}
}
我认为这是使用改装从服务器获取信息的一种常见的典型方式,对吗?
View 在其 View Model 中调用一个方法来获取要显示的内容
并且视图模型调用其存储库中的方法来获取数据,即该代码中的userList
。
我确实得到了我需要的数据。 response.code().toString()
工作正常
response.body()!!.toString()
工作正常,一切正常。 body 包含我所期望的。
第二个日志也工作正常。
但问题是,
无论 body 包含什么,此函数 return 在末尾都为 null。
我知道这是因为 enqueue
运行 是异步的,
所以方法 return 在 onResponse
方法响应并将数据保存到 userList
之前为 null。
证据是在returning 之前执行的第三条日志高于onResponse
中的所有日志。
那么如何让这个方法等待 onResponse
在 return 之前完成它的工作?
或者,即使在方法 returning 之后,我怎样才能使 View 得到一个字符串 onResponse
?
我试过 execute()
但它不起作用,因为它不能也不应该在主线程上 运行 并且 android 拒绝它。
感谢您的所有评论和回答。
一般情况下,您需要在调用onResponse 时实现某种回调。
class MainRepository(private val userApi: UserApi) {
fun getUserList(resultCallback : ResultCallback) {
var userList : ArrayList<User>? = null
userApi.getAllUser().enqueue(object : Callback<ArrayList<User>> {
override fun onResponse(call: Call<ArrayList<User>>, response: Response<ArrayList<User>>) {
if (response.body() != null) {
Log.e("user list succeed", response.body()!!.toString())
resultCallback.onResult(response.body()!!)
}
}
override fun onFailure(call: Call<ArrayList<User>>, t: Throwable) {
Log.e("user list fail", t.message!!)
resultCallback.onFailure(t.message!!)
}
})
Log.e("this log", "shouldn't be above the logs in onResponse ")
}
}
然后在代码中的某处传递此回调并等待结果并对结果做一些事情(例如在 RecyclerView 上显示)。我不知道它应该如何与 MVVM 一起工作,但这是监听异步操作的常用方法。
您也可以使用 RxJava 来实现该行为
为什么不尝试使用实时数据?
所以你的视图模型将包含这个而不是你的函数
fun getUserName() : LiveData<ResponseBody> = fooRepository.getUserName()
你的存储库将是这样的
class MainRepository() {
fun getUserList() : LiveData<ResponseBody> {
MutableLiveData<ResponseBody> data = new MutableLiveData<>();
var userList : ArrayList<User>? = null
userApi.getAllUser().enqueue(object : Callback<ResponseBody> {
override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
if (response.body() != null) {
data.postValue(response.body().);
}
}
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
data.postValue(null);
}
})
Log.e("this log", "shouldn't be above the logs in onResponse ")
}
}
ReponseBody class 将包含来自 api
的回复
终于在你的 activity
mainViewModel.getUserList().observe(this,
Observer<ApiResponse> { apiResponse ->
if (apiResponse != null) {
// handle your response in case of success
}
else {
// call failed.
}
})
如何让一个函数等到其中的改造方法在 return 之前得到响应?
我在 Stack Overflow 上看到了很多问题和答案,但由于愚蠢或我没有完全理解它们。
我有一个视图模型,它为视图提供要在屏幕上显示的文本。
喜欢,我确实喜欢这个观点,activity_foo.xml:
android:text = "@{fooViewModel.getUserName()}"
并且在视图模型中 class:
fun getUserName() : String = fooRepository.getUserName()
我想你会明白这个策略,因为它在 MVVM 模式中很常见。
所以 FooRepository,我的意思是我的视图模型的真实存储库如下所示:
class MainRepository(private val userApi: UserApi) {
fun getUserList() : ArrayList<User>? {
var userList : ArrayList<User>? = null
userApi.getAllUser().enqueue(object : Callback<ArrayList<User>> {
override fun onResponse(call: Call<ArrayList<User>>, response: Response<ArrayList<User>>) {
if (response.body() != null) {
Log.e("user list succeed", response.body()!!.toString())
userList = response.body()!!
Log.e("user list saved", userList!![0].id)
}
}
override fun onFailure(call: Call<ArrayList<User>>, t: Throwable) {
Log.e("user list fail", t.message!!)
}
})
Log.e("this log", "shouldn't be above the logs in onResponse ")
return userList
}
}
我认为这是使用改装从服务器获取信息的一种常见的典型方式,对吗?
View 在其 View Model 中调用一个方法来获取要显示的内容
并且视图模型调用其存储库中的方法来获取数据,即该代码中的userList
。
我确实得到了我需要的数据。 response.code().toString()
工作正常
response.body()!!.toString()
工作正常,一切正常。 body 包含我所期望的。
第二个日志也工作正常。
但问题是,
无论 body 包含什么,此函数 return 在末尾都为 null。
我知道这是因为 enqueue
运行 是异步的,
所以方法 return 在 onResponse
方法响应并将数据保存到 userList
之前为 null。
证据是在returning 之前执行的第三条日志高于onResponse
中的所有日志。
那么如何让这个方法等待 onResponse
在 return 之前完成它的工作?
或者,即使在方法 returning 之后,我怎样才能使 View 得到一个字符串 onResponse
?
我试过 execute()
但它不起作用,因为它不能也不应该在主线程上 运行 并且 android 拒绝它。
感谢您的所有评论和回答。
一般情况下,您需要在调用onResponse 时实现某种回调。
class MainRepository(private val userApi: UserApi) {
fun getUserList(resultCallback : ResultCallback) {
var userList : ArrayList<User>? = null
userApi.getAllUser().enqueue(object : Callback<ArrayList<User>> {
override fun onResponse(call: Call<ArrayList<User>>, response: Response<ArrayList<User>>) {
if (response.body() != null) {
Log.e("user list succeed", response.body()!!.toString())
resultCallback.onResult(response.body()!!)
}
}
override fun onFailure(call: Call<ArrayList<User>>, t: Throwable) {
Log.e("user list fail", t.message!!)
resultCallback.onFailure(t.message!!)
}
})
Log.e("this log", "shouldn't be above the logs in onResponse ")
}
}
然后在代码中的某处传递此回调并等待结果并对结果做一些事情(例如在 RecyclerView 上显示)。我不知道它应该如何与 MVVM 一起工作,但这是监听异步操作的常用方法。
您也可以使用 RxJava 来实现该行为
为什么不尝试使用实时数据?
所以你的视图模型将包含这个而不是你的函数
fun getUserName() : LiveData<ResponseBody> = fooRepository.getUserName()
你的存储库将是这样的
class MainRepository() {
fun getUserList() : LiveData<ResponseBody> {
MutableLiveData<ResponseBody> data = new MutableLiveData<>();
var userList : ArrayList<User>? = null
userApi.getAllUser().enqueue(object : Callback<ResponseBody> {
override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
if (response.body() != null) {
data.postValue(response.body().);
}
}
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
data.postValue(null);
}
})
Log.e("this log", "shouldn't be above the logs in onResponse ")
}
}
ReponseBody class 将包含来自 api
的回复终于在你的 activity
mainViewModel.getUserList().observe(this,
Observer<ApiResponse> { apiResponse ->
if (apiResponse != null) {
// handle your response in case of success
}
else {
// call failed.
}
})