Android Метод постановки в очередь дооснащения не возвращает значение - PullRequest
2 голосов
/ 02 августа 2020
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
    }

Метод постановки в очередь выполняется в фоновом потоке, но как вернуть список внутри метода постановки в очередь. Приведенный выше код возвращает пустой список. Заранее спасибо

Ответы [ 2 ]

4 голосов
/ 02 августа 2020

Как вы уже упоминали, enqueue будет выполнять этот вызов API в фоновом потоке, поэтому ваша функция всегда будет возвращать пустой список, так как сейчас ответ от API не получен, поэтому это l oop, о котором вы упомянули: -

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

Этот l oop будет запущен позже (когда будет получен ответ от 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)
}

Теперь здесь с помощью обратных вызовов успеха и неудачи вы можете обрабатывать оба случая.

1 голос
/ 02 августа 2020

Это асинхронный вызов, поэтому 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, чтобы знать, если сеть запрос не выполнен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...