【问题标题】:Android Retrofit enqueue method does not return valueAndroid Retrofit enqueue 方法不返回值
【发布时间】:2020-08-02 22:38:50
【问题描述】:
fun getSurvey() : MutableList<SurveyMaster>{
        //Retrofit creates implementation for this method getSurveyList()
        val call : Call<List<SurveyMaster>> = retrofitPlaceHolderAPI.getSurveyList("bearer "+customIDToken)

        val surveyList =   mutableListOf<SurveyMaster>()

        //enqueue - executing on the background thread, to execute asynchronously
        call.enqueue(object : Callback<List<SurveyMaster>>{
            override fun onFailure(call: Call<List<SurveyMaster>>, t: Throwable) {
                Log.e("Error", t.message)
                //Log.e("Error", t.localizedMessage)
            }

            override fun onResponse(call: Call<List<SurveyMaster>>, response: Response<List<SurveyMaster>>) {
                if (!response.isSuccessful){
                    Log.e("SurveyList Error", "code: "+response.code())
                    return
                }

                val surveys = response.body()

                for(element in surveys!!){
                    surveyList.add(element)
                }
            }
        })
        return surveyList
    }

Enqueue 方法在后台线程上运行,但是如何在 enqueue 方法中返回列表。上面的代码返回空列表。提前致谢

【问题讨论】:

标签: android api http kotlin retrofit


【解决方案1】:

就像您已经提到的那样,入队将在后台线程上执行此 API 调用,因此您的函数将始终返回空列表,因为目前尚未收到来自 API 的响应,因此您提到的这个循环:-

for(element in surveys!!){
    surveyList.add(element)
}

这个循环将在稍后运行(当收到来自 API 的响应时)同时你已经返回了此时为空的列表。这里你不能直接从方法返回数据。

您可以通过接口使用回调方法。由于您已经以列表的形式获得响应,因此无需创建单独的列表并将数据添加到其中。

fun getSurvey(onGetSurveyListener: OnGetSurveyListener){

    val call : Call<List<SurveyMaster>> = retrofitPlaceHolderAPI.getSurveyList("bearer "+customIDToken)

    val surveyList =   mutableListOf<SurveyMaster>()

    //enqueue - executing on the background thread, to execute asynchronously
    call.enqueue(object : Callback<List<SurveyMaster>>{
        override fun onFailure(call: Call<List<SurveyMaster>>, t: Throwable) {
            Log.e("Error", t.message)
            onGetSurveyListener.onGetSurveyFailure(t.localizedMessage)
            //Log.e("Error", t.localizedMessage)
        }

        override fun onResponse(call: Call<List<SurveyMaster>>, response: Response<List<SurveyMaster>>) {
            if (!response.isSuccessful){
                Log.e("SurveyList Error", "code: "+response.code())
                return
            }
            response.body?.let{list->
               onGetSurveyListener.onGetSurveySuccess(list)
            }
        }
    })
}

interface OnGetSurveyListener {
    fun onGetSurveySuccess(surveyList:List<SurveyMaster>)
    fun onGetSurveyFailure(errorMessage: String)
}

现在有了成功和失败回调,您可以处理这两种情况。

【讨论】:

  • 即使错误回调是可选的,添加到答案中也是一个不错的选择,因为它允许 OP 也可以“移动”错误消息而不仅仅是数据
  • 正是@a_local_nobody。顺便说一句,你的问题解决了吗?
  • 很高兴能得到任何帮助 @vishnujm 。如果您的问题得到解决,请您接受答案。
  • @AdityaTyagi 感谢您的反馈!声望低于 15 人的投票将被记录,但不会更改公开显示的帖子得分。
  • @vishnujm 不用担心没问题,它解决了你接受的问题,这就足够了:)
【解决方案2】:

这是一个异步调用,所以 onResponse 在网络调用成功后被调用,并且您在此之前返回列表。您需要使用回调返回数据。像这样修改你的函数:

fun getSurvey(onComplete: (MutableList<SurveyMaster>) -> Unit) {
    //Retrofit creates implementation for this method getSurveyList()
    val call : Call<List<SurveyMaster>> = retrofitPlaceHolderAPI.getSurveyList("bearer "+customIDToken)
    
    val surveyList =   mutableListOf<SurveyMaster>()
    
    //enqueue - executing on the background thread, to execute asynchronously
    call.enqueue(object : Callback<List<SurveyMaster>>{
        override fun onFailure(call: Call<List<SurveyMaster>>, t: Throwable) {
            Log.e("Error", t.message)
            //Log.e("Error", t.localizedMessage)
        }
        
        override fun onResponse(call: Call<List<SurveyMaster>>, response: Response<List<SurveyMaster>>) {
            if (!response.isSuccessful){
                Log.e("SurveyList Error", "code: "+response.code())
                return
            }
            
            val surveys = response.body()
            
            for(element in surveys!!){
                surveyList.add(element)
            }
            onComplete.invoke(surveyList)
        }
    })
}

然后像这样调用你的方法:

    getSurvey { list ->
      // Do something with your list.
    }

根据您的问题,您可能还希望返回一些 onFailure 事件以了解网络请求是否成功。

【讨论】:

  • 我为此类问题制作了一个模板,如果您想要参考一些易于复制的回调模式:here
猜你喜欢
  • 2020-09-18
  • 2015-04-30
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2016-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多