Kotlin 在异步进度结束时返回

Posted

技术标签:

【中文标题】Kotlin 在异步进度结束时返回【英文标题】:Kotlin return when asynchronous progress ends 【发布时间】:2021-12-26 03:34:06 【问题描述】:

我正在尝试从下载文件的函数中返回布尔值。 但是在进度处理程序中,我无法将“true”语句返回给函数。

我发现一些文章附加了一个接口以进行通信,但不幸的是我无法让这个 okhttpd 函数工作。

还有其他选择吗?这是我正在使用的代码。

private fun downloadFile(url: String,key: String):Boolean 
    
        val formBody: RequestBody = FormBody.Builder()
            .add("key", key)
            .build()

        val downloadClient = OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(180, TimeUnit.SECONDS).readTimeout(180, TimeUnit.SECONDS)
            .build()

        val request: Request = Request.Builder()
            .url(url)
            .post(formBody)
            .addHeader("typeAttach", "download")
            .build()
    

        downloadClient.newCall(request).enqueue(object : Callback 

            override fun onFailure(call: Call, e: IOException) 
                Log.e("failure Response", e.toString())
                call.cancel()
            

            override fun onResponse(call: Call, response: Response) 
                val tmpDl = File(globalPath, Utility.tmpDir + "/test.zip")
                val sourceBytes = response.body!!.source()
                val sourceSize = response.body!!.contentLength()
                val sink: BufferedSink = tmpDl.sink().buffer()

                var totalRead: Long = 0
                var lastRead: Long

                while (sourceBytes
                        .read(sink.buffer, 8L * 1024)
                        .also  lastRead = it  != -1L
                ) 
                    totalRead += lastRead
                    sink.emitCompleteSegments()

                    Log.d("progress”, totalRead + "/" + sourceSize)

                
                //return true when its finished

                sink.writeAll(response.body!!.source())
                sink.close()
            


        )

 return false
    

【问题讨论】:

你对返回的布尔值做了什么? ***.com/questions/57330766/… 您的问题与您所看到的使用接口的问题相比没有什么不同,它也应该在这里工作,只需在onFailureonResponse 中调用回调 首先调用该函数是可以的,它不关心结果,这就是为什么它被定义所以你不能返回任何东西。将您的主应用程序想象成一个人在工作,而异步调用就像让其他人去做一项任务。该回调是他们完成后应该做的工作 如果你使用协程和挂起函数并在没有入队的情况下点击请求怎么办。否则回调也是一个好方法。 【参考方案1】:

使用回调尝试下一个方法:

private fun downloadFile(
  url: String,
  key: String, 
  downloadCompleteCallback: () -> Unit
)  
 // your code

并在while循环中通知下载完成:

while (sourceBytes.read(sink.buffer, 8L * 1024).also  
    lastRead = it  != -1L) 

  totalRead += lastRead
  sink.emitCompleteSegments()

  if (totalRead == 100) 
    downloadCompleteCallback.invoke()
                    

【讨论】:

我认为你的回调应该是downloadCompleteCallback: (Boolean) -> Unit,这样你就可以通过true或false,或者多个回调也是一种方法,目前OP真的没有办法知道它失败的。从基本解释的角度来看,它可能很好:) @Manuel 和 a_local_nobody 感谢您的回复,这是对我问题的正确答案。我将自己深入研究。

以上是关于Kotlin 在异步进度结束时返回的主要内容,如果未能解决你的问题,请参考以下文章

与 kotlin 异步运行代码的最佳方法

对比Java学Kotlin协程-异步流

对比Java学Kotlin协程-异步流

对比Java学Kotlin协程-异步流

对比Java学Kotlin协程-异步流

Kotlin 协程Flow 异步流 ② ( 使用 Flow 异步流持续获取不同返回值 | Flow 异步流获取返回值方式与其它方式对比 | 在 Android 中使用 Flow 异步流下载文件 )