首页 > 解决方案 > 如何让一个方法等到它的改造方法在返回之前得到它的响应?

问题描述

如何让函数等到其中的改造方法在返回之前得到响应?

我在 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 也拒绝它。

感谢您的所有评论和回答。

标签: androidretrofitretrofit2

解决方案


为什么不尝试使用实时数据?

所以你的视图模型将包含这个而不是你的函数

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.

            }
        })

推荐阅读