Android kotlin l oop для извлечения данных с помощью OkHttp - PullRequest
0 голосов
/ 27 марта 2020

Я могу получить данные с помощью метода okhttp.enqueue, как указано ниже:

var url = "www.test.com?page="
var pageNumber = 1
var looper = true


// Should the below codes be placed into a `while(looper) { }` loop ??
val urlRequest = Request.Builder()
    .url(StringBuilder().append(url).append("$pageNumber").toString())
    .build()

httpClient.newCall(urlRequest).enqueue(object : Callback {
    override fun onFailure(call: Call, e: IOException) {
        Log.i("test", "API call Failed: $call, $e")
    }

    override fun onResponse(call: Call, response: Response) {
        val dataString = response.body?.string()  // parse the data into String
        val gsonResult = GsonBuilder().create()     // create a json object
        val finalData = gsonResult.fromJson(dataString, FinalData::class.java)
        if (finalData.value.isNullOrEmpty()) {
            Log.i("test", "data is empty...  $pageNumber")   
            // When wrapping this code in a while loop, I would write `looper = false` here to break out             
        } else {  
            val a = finalData .value.size
            println("$a, $pageNumber")
        }
    }
})

pageNumber++

однако, когда я обертываю это вокруг while l oop, чтобы динамически заполнить pageNumber для динам c выборка. Я заметил, что код не ждет onResponse перед тем, как перейти на 2-ю страницу вперед.

Я понимаю, что OkHttp является асин c, и это, вероятно, то, что происходит для кода, чтобы продолжить выполнение без ожидания onResponse.

Мой вопрос: как правильно обрабатывать циклы такого рода, чтобы динамически увеличивать pageNumber для запроса HTTP GET?

Примечание: Это на Android. Так что не похоже, что они позволяют мне запускать такие задачи в потоке MainUI.

Кроме того, возможно ли получить call ответ из другой функции? okhttp, кажется, не позволяет такую ​​вещь.

1 Ответ

0 голосов
/ 27 марта 2020

Самый простой ответ - просто использовать execute вместо enqueue, если вас устраивает блокировка императивного кода.

package xxx

import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.IOException

fun main() {
  val url = "www.test.com?page="
  var pageNumber = 1

  val httpClient = OkHttpClient()

  try {
    while (true) {
      val urlRequest = Request.Builder().url("$url$pageNumber").build()

      httpClient.newCall(urlRequest)
          .execute()
          .use { response ->

            val dataString = response.body?.string()  // parse the data into String
            val gsonResult = GsonBuilder().create()     // create a json object
            val finalData = gsonResult.fromJson(dataString, FinalData::class.java)
            if (finalData.value.isNullOrEmpty()) {
              Log.i("test", "data is empty...  $pageNumber")
              // When wrapping this code in a while loop, I would write `looper = false` here to break out
            } else {
              val a = finalData.value.size
              println("$a, $pageNumber")
            }
          }

      pageNumber++
    }
  } catch (e: IOException) {
      Log.i("test", "API call Failed: $call, $e")
  }
}
...