Методы возвращают нулевое значение перед выполнением Обратного вызова Retrofit - PullRequest
1 голос
/ 01 апреля 2020

При работе с шаблоном MVVM в Android разработках мы создаем класс репозитория, в котором мы выполняем все сетевые запросы. Проблема заключается в том, что метод .enqueue () в Retrofit является асинхронным, мой метод, который вызывает .enqueue, не ждет, пока не будет получен обратный вызов (что довольно логично), и возвращает ноль. Одним из способов решения этой проблемы является передача объекта 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!!
    }

Ответы [ 2 ]

2 голосов
/ 01 апреля 2020

Передайте обратный вызов в качестве аргумента, например,

createRoute(newRoute: RouteToSend, callback: CreateRouteListener)

с

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

и вызовите соответствующий метод, когда завершится асинхронный c процесс:

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
    }
}
1 голос
/ 01 апреля 2020

Да, использование 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
    }
})
...