Home > database >  Kotlin return when asynchronous progress ends
Kotlin return when asynchronous progress ends

Time:11-16

I am trying to return a Boolean from a function that downloads a file. But inside the progress handler I can't return the "true" statement back to the function.

I found some articles to append an interface to communicate back but unfortunately I can't get this to work for this okhttpd function.

Are there other alternatives? This is the code I am using.

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
    
}

CodePudding user response:

Try the next approach using a callback:

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

And in the while loop notify the download is complete:

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

  if (totalRead == 100) {
    downloadCompleteCallback.invoke()
  }                  
}
  • Related