Будет ли следующий код пропускать ресурсы при отмене сопрограммы Kotlin?
Общие сведения: код вложен во ViewModel! Метод retrievePDFDocument будет запущен в событии onStart фрагмента.
fun retrievePDFDocument() {
job = viewModelScope.launch {
withContext(Dispatchers.IO) {
downloadFile(assetPath.value!!)
}
}
}
А здесь функция приостановки:
private fun downloadFile(strPdfUrl: String): File? {
var inputStream: InputStream? = null
val lenghtOfFile: Int //lenghtOfFile is used for calculating download progress
//this is where the file will be seen after the download
var fileOut: FileOutputStream? = null
var localPDFFile: File? = null
if(strPdfUrl.isBlank())
return localPDFFile
try {
val pdfUrl = URL(strPdfUrl)
val urlConnection = pdfUrl.openConnection() as HttpURLConnection
if (urlConnection.responseCode == 200) {
//file input is from the url
inputStream = BufferedInputStream(urlConnection.inputStream)
lenghtOfFile = urlConnection.contentLength
localPDFFile = File(localPdfDirectory, pdfFileName.value!!)
fileOut = FileOutputStream(localPDFFile)
//here’s the download code
val buffer = ByteArray(1024)
var total: Long = 0
while (true) {
// If coroutine is cancelled
// a CancellationException will be thrown here
// Do not more work then necesarry
coroutineContext.ensureActive()
val length = inputStream.read(buffer)
if (length <= 0) break
total += length.toLong()
_currProgress.postValue( (total * 100 / lenghtOfFile).toInt() )
fileOut.write(buffer, 0, length)
}
}
} catch (e: IOException) {
Log.e("PdfViewerViewModel - downloadFile Error: ${e.message}")
localPdfFile?.delete() // remove partially downloaded file
localPDFFile = null
} catch (e1: CancellationException) {
Log.e("PdfViewerViewModel - downloadFile CancellationException: ${e1.message}")
localPdfFile?.delete() // remove partially downloaded file
localPdfFile = null
finally {
try {
inputStream?.close()
fileOut?.apply {
flush()
close()
}
} catch (e1: IOException) { //do nothing here }
}
return localPDFFile
}
С уважением, Франк
@ Обновление 10.04 .2020 Реализация с coroutineContext.ensureActive () и перехват исключения