【问题标题】:Updating Recyclerview adapter from suspend function从挂起功能更新 Recyclerview 适配器
【发布时间】:2020-10-27 02:17:59
【问题描述】:

我正在尝试从书籍 api 加载和显示书籍,但信息未显示。如果我使用调试器并单步执行,但不是从一开始就可以显示它。

    val client = OkHttpClient()
    val request = Request.Builder()
        .url(url)
        .build()

    client.run {
        newCall(request).enqueue(object : Callback {
            override fun onFailure(call: okhttp3.Call, e: IOException) {
                e.printStackTrace()
            }

            override fun onResponse(call: okhttp3.Call, response: Response) {
                if (!response.isSuccessful) {
                    System.err.println("Response unsuccessful")
                    return
                }
                val response = response.body?.string()
                val books = response?.let { parse(it) }
                if (books != null) {
                    list.addAll(books.bookItems)
                }
            }
        })
        delay(500)
    }
    return list
}

编辑:只需要增加延迟时间并移除 renderBooks() 调用

【问题讨论】:

    标签: android kotlin android-recyclerview kotlin-coroutines android-mvp


    【解决方案1】:

    在片段视图初始化之前调用presenter.getBooks。试试把它放在onViewCreated里面。

    【讨论】:

    • 您好,我试过了,创建时仍然没有显示。它在单步执行 loadBooks() 时显示,并显示“在线程 OKhttp 中达到断点 ...”,然后它就可以显示了。它还说“Async Stacktrace || Invoke Suspend”
    【解决方案2】:

    这种延迟似乎非常错误。 您对数据的所有请求都需要 500 毫秒。如果花费的时间更长,您将得不到任何数据,如果花费的时间更少,那么您就没有必要等待了。

    我认为这在使用调试器时有效,因为您让函数在返回语句之前等待更长的时间。

    正确的解决方案是使用suspendCoroutine

    return suspendCoroutine { cont ->
       val client = OkHttpClient()
       val request = Request.Builder()
           .url(url)
           .build()
    
       client.run {
           newCall(request).enqueue(object : Callback {
               override fun onFailure(call: okhttp3.Call, e: IOException) {
                  cont.resumeWithException(e)
               }
    
               override fun onResponse(call: okhttp3.Call, response: Response) {
                   if (!response.isSuccessful) {
                       System.err.println("Response unsuccessful")
                       cont.resume(emptyList())
                   }
                   val items = response.body?.string()
                            ?.let { parse(it) }
                            ?.bookItems
                            .orEmpty()
                   cont.resume(items)
               }
           })
        }
    }
    

    您可能需要将对字符串的调用包装在 try catch 中,以从读取输入字符串中捕获任何 IOException。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-23
      • 2019-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多