【问题标题】:Methods returns a null value before Retrofit Callbacks are executed方法在执行改造回调之前返回一个空值
【发布时间】:2020-04-01 16:18:15
【问题描述】:

在 Android 开发中使用 MVVM 模式时,我们创建了一个存储库类,我们在其中执行所有网络请求。问题是由于改造的 .enqueue() 方法是异步的,我调用 .enqueue 的方法不会等到回调获得(这很合乎逻辑)并返回 null。 解决此问题的一种方法是将 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!!
    }

【问题讨论】:

    标签: android kotlin retrofit


    【解决方案1】:

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

    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
        }
    }
    

    【讨论】:

      【解决方案2】:

      是的,使用 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
          }
      })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-07
        • 2018-02-08
        • 2016-07-26
        • 1970-01-01
        • 2022-01-24
        • 2013-06-03
        • 2020-02-10
        • 2020-03-31
        相关资源
        最近更新 更多