Android 如何使一种方法等到其改造方法得到响应后再返回?

Android 如何使一种方法等到其改造方法得到响应后再返回?,android,retrofit,retrofit2,Android,Retrofit,Retrofit2,如何让一个函数等到它的一个改进方法得到响应后再返回 我已经看到了很多关于堆栈溢出的问题和答案,但由于愚蠢或其他原因,我没有完全理解它们 我有一个视图模型,它给视图一个文本显示在屏幕上 比如,我确实喜欢这个视图,activity_foo.xml: android:text=@{fooViewModel.getUserName} 在视图模型类中: fun getUserName() : String = fooRepository.getUserName() 我认为您会得到该策略,因为它在MVVM

如何让一个函数等到它的一个改进方法得到响应后再返回

我已经看到了很多关于堆栈溢出的问题和答案,但由于愚蠢或其他原因,我没有完全理解它们

我有一个视图模型,它给视图一个文本显示在屏幕上

比如,我确实喜欢这个视图,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
    }
}
我认为这是一种通常的、典型的通过改造从服务器获取信息的方法,对吗

视图在其视图模型中调用一个方法以获取要显示的内容

视图模型调用其存储库中的方法来获取数据,即代码中的userList

我确实得到了我需要的数据。response.code.toString工作正常

回应,身体!!。toString很好,一切都很好。身体里正是我所期望的

第二根圆木也很好用

但问题是,

此函数在该体包含的内容的末尾返回null

我知道这是因为排队是异步运行的

因此,在onResponse方法响应并将数据保存到userList之前,该方法返回null

证明是在返回之前执行的第三个日志高于onResponse中的所有日志

那么,如何让这个方法等待onResponse完成它的工作,然后再返回呢

或者,即使在方法返回后,我如何使View获得一个字符串onResponse呢

我尝试过执行,但它不起作用,因为它不能也不应该在主线程上运行,而且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实现这种行为

通常,在调用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类将包含来自api的响应 最后在你的活动中

 mainViewModel.getUserList().observe(this,
        Observer<ApiResponse> { apiResponse ->
            if (apiResponse != null) {
                // handle your response in case of success
            }
             else {
                // call failed.

            }
        })
为什么不尝试使用实时数据? 因此,视图模型将包含此项,而不是函数

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.

            }
        })

哦,天哪。。我想我现在得到了,但我找不到ResultCallback接口。我无法导入它。它只是尝试导入is CarrierMessageService.ResultCallback。但是谢谢你。你必须创建自己的自定义回拨哦,天哪。。我想我现在得到了,但我找不到ResultCallback接口。我无法导入它。它只是尝试导入is CarrierMessageService.ResultCallback。但是谢谢你。你必须创建自己的自定义callbackGosh,我忘记了LiveData。谢谢你,尽管我用了另一种方式。我没有让活动观察livedata,而是让视图观察。天哪,我忘记了livedata。谢谢你,尽管我用了另一种方式。我没有做任何活动来观察livedata,但是视图做了。