方法 returns 执行 Retrofit 回调之前的空值

Methods returns a null value before Retrofit Callbacks are executed

在 Android 开发中使用 MVVM 模式时,我们创建了一个存储库 class,我们在其中执行所有网络请求。问题是因为 retrofit 的 .enqueue() 方法是异步的,我调用 .enqueue 的方法不会等到获得回调(这是非常合乎逻辑的)并且 returns 为空。 解决此问题的一种方法是将 MutableLiveData 对象传递到我的存储库方法并在回调中设置它的值,但我不想在我的视图(片段)中观察我的所有 ViewModel 属性。 解决这个问题的常用方法是什么?

fun createRoute(newRoute: RouteToSend): String {
        var responseMessage: String? = null
        webService.createRoute(authToken!!, newRoute).enqueue(object: Callback<Message> {
            override fun onFailure(call: Call<Message>, t: Throwable) {
                Log.e(TAG, t.message!!)
            }

            override fun onResponse(call: Call<Message>, response: Response<Message>) {
                response.body()?.let { responseMessage = it.message }
            }
        })
        return responseMessage!!
    }

将回调作为参数传递,例如

createRoute(newRoute: RouteToSend, callback: CreateRouteListener)

interface CreateRouteListener {
    fun onFailure()
    fun onResponse(response: String)
}

并在异步进程结束时调用相应的方法:

override fun onFailure(call: Call<Message>, t: Throwable) {
    Log.e(TAG, t.message!!)
    callback.onFailure()
}

override fun onResponse(call: Call<Message>, response: Response<Message>) {
    response.body()?.let {
        responseMessage = it.message
        callback.onResponse(responseMessage)
    }
}

调用 createRoute 将如下所示:

createRoute(RouteToSend(), object: CreateRouteListener {
    override fun onFailure() {
        // handle failure
    }
    override fun onResponse(response: String) {
        // handle response
    }
}

是的,使用 MutableLiveData 是一种方法,另一方面使用回调机制是另一种更合适的方法。 如果你想使用回调,你可以改变你的方法,比如

fun createRoute(newRoute: RouteToSend, callback : (String?) -> Unit): String {
        var responseMessage: String? = null
        webService.createRoute(authToken!!, newRoute).enqueue(object: Callback<Message> {
            override fun onFailure(call: Call<Message>, t: Throwable) {
                Log.e(TAG, t.message!!)
callback(responseMessage)
            }

            override fun onResponse(call: Call<Message>, response: Response<Message>) {
                response.body()?.let { responseMessage = it.message 
callback(responseMessage)}
            }
        })

    }

然后你可以像这样调用你的 createRoute 方法

createRoute(route_to_send_variable, 
    callback = {
        it?.let {
            // use the response of your createRoute function here
    }
})