android - 如何让一个方法等到它的改造方法在返回之前得到它的响应?
问题描述
如何让函数等到其中的改造方法在返回之前得到响应?
我在 Stack Overflow 上看到了很多问题和答案,但是因为愚蠢或者我没有完全理解它们。
我有一个视图模型,它为视图提供了要在屏幕上显示的文本。
就像,我确实喜欢这样,activity_foo.xml:
android:text = "@{fooViewModel.getUserName()}"
并在视图模型类中:
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()
工作正常,一切正常。身体包含的正是我所期望的。
第二个日志也可以正常工作。
但问题是,
无论正文包含什么,此函数都会在末尾返回 null。
我知道这是因为它enqueue
异步运行,
因此该方法在方法响应之前返回 nullonResponse
并将数据保存到userList
.
证明是在返回之前执行的第三个日志首先是所有日志onResponse
。
那么我怎样才能让这个方法在返回之前等待onResponse
完成它的工作呢?
onResponse
或者,即使在方法返回之后 ,如何让 View 获得一个字符串?
我试过execute()
但它不起作用,因为它不能也不应该在主线程上运行,而且 android 也拒绝它。
感谢您的所有评论和回答。
解决方案
为什么不尝试使用实时数据?
所以你的视图模型将包含这个而不是你的函数
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 类将包含您来自 api 的响应
最后在你的活动中
mainViewModel.getUserList().observe(this,
Observer<ApiResponse> { apiResponse ->
if (apiResponse != null) {
// handle your response in case of success
}
else {
// call failed.
}
})
推荐阅读
- amazon-web-services - 从浏览器将图像文件上传到 AWS Lambda .Net Core 应用程序会导致文件不可用 - 如何修复?
- python - 将具有重复的numpy数组与列表进行比较
- aws-lambda - 如何将一个值注入到“lambda_handler”的事件参数中以进行测试?
- c# - 如何在 WinForms 中为运行时制作的图片框制作子框
- bash - 查找和替换文件中的字符串(macOS bash 脚本)?
- jquery - 显示来自 JSON 数据的随机值
- memory - C/C++,对象二进制是否跨平台兼容?
- html - 如何将我的 h2 标题更改为
文本同时保持大小和对齐?
- c# - 如何在 xamarin 表单图像标签中使用 url+binding
- python - 我的时间戳字符串末尾有“-05:00”,这是什么意思,我该如何处理?