Vivek Modi
05/10/2021, 11:44 AMclass FileDownloader {
companion object {
private const val BUFFER_LENGTH_BYTES = 1024 * 8
private const val HTTP_TIMEOUT = 30
}
private var okHttpClient: OkHttpClient
init {
val okHttpBuilder = okHttpClient.newBuilder()
.connectTimeout(HTTP_TIMEOUT.toLong(), TimeUnit.SECONDS)
.readTimeout(HTTP_TIMEOUT.toLong(), TimeUnit.SECONDS)
this.okHttpClient = okHttpBuilder.build()
}
fun download(url: String, file: File): {
val request = Request.Builder().url(url).build()
val response = okHttpClient.newCall(request).execute()
val body = response.body
val responseCode = response.code
if (responseCode >= HttpURLConnection.HTTP_OK &&
responseCode < HttpURLConnection.HTTP_MULT_CHOICE &&
body != null) {
val length = body.contentLength()
body.byteStream().apply {
file.outputStream().use { fileOut ->
var bytesCopied = 0
val buffer = ByteArray(BUFFER_LENGTH_BYTES)
var bytes = read(buffer)
while (bytes >= 0) {
fileOut.write(buffer, 0, bytes)
bytesCopied += bytes
bytes = read(buffer)
}
}
}
} else {
throw IllegalArgumentException("Error occurred when do http get $url")
}
}
}
}
knthmn
05/11/2021, 7:35 AMRequest.execute()
, you can use Request.enqueue()
to make it non blocking
• Make your download
a suspend fun
, and use ensureActive()
or yield()
in the transfer loopVivek Modi
05/11/2021, 8:44 AMRequest.enqueue()
is asking callbackknthmn
05/11/2021, 9:12 AMsuspendCancellableCoroutine()
to convert it to a suspend function, remember to close the Response
knthmn
05/11/2021, 9:15 AM