Загрузка файлов из списка URL-адресовAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Загрузка файлов из списка URL-адресов

Сообщение Anonymous »

Мне нужно скачать файлы из списка URL-адресов. Размер URL-адресов списка составляет от 3000 до 6000. Эти файлы имеют небольшой размер, самый большой из них составляет 25 КБ. У меня есть функция, которая может загрузить файл, но при использовании для нескольких файлов, как в этом случае, она оказывает давление на кучу, поскольку экземпляры объектов создаются на лету для каждого загружаемого URL-адреса. Функция приведена ниже:

Код: Выделить всё

fun download(
dest: File,
url: String,
filename: String,
onPreExecute: () -> Unit = {},
onPostExecute: (Any) -> Unit = {},
onProgress: (DownloadState) -> Unit = {},
): Job {
return appScope.executeAsyncTask(
onPreExecute = onPreExecute,
onPostExecute = onPostExecute,
onProgress = onProgress,
doInBackground = { reportProgress: suspend (progress: DownloadState) ->  Unit ->
try {
val httpUrl = URL(url)
val connection = httpUrl.openConnection()
connection.connect()
val totalBytes = connection.contentLengthLong
httpUrl.openStream().use { ins ->
BufferedInputStream(ins).use { bis ->
FileOutputStream(File(dest, filename)).use { fos ->
var bytesRead: Int
var totalBytesRead = 0L
val buffer = ByteArray(4096)
// Downloading started
val ds = DownloadState(
downloading = true,
fileSizeBytes = totalBytes
)
while (
bis.read(
/* b = */ buffer,
/* off = */0,
/* len = */buffer.size
).also { bytesRead = it } != -1
) {
totalBytesRead += bytesRead
// Report download progress
reportProgress(
ds.copy(
bytesDownloaded = totalBytesRead,
progress = (totalBytesRead / totalBytes.toFloat())
)
)
fos.write(buffer, 0, bytesRead)
}
// Downloading finished
reportProgress(ds.copy(downloading = false))
}
}
}
} catch (e: Exception) {
e.printStackTrace()
Log.e(TAG, e.message.toString())
reportProgress(DownloadState(error = e, downloading = false))
throw e
}
}
)
}
Я вызываю эту функцию в модели представления следующим образом:

Код: Выделить всё

private fun download(directory: File) {
viewModelScope.launch {
try {
val audios = listOf(/* Audio(...) */)

if (isExternalStorageWritable()) {
audios.forEachIndexed { i, s ->
val count = i + 1
val id = s.id
val done = count == audios.size

val filename = audio.getFilename(id)
val dest = File(directory, audio.getDirectory())

if (!dest.exists()) dest.mkdirs()

// If file already exists skip it
if (File(dest, filename).exists()) {
_uiState.update {
val audioCount = it.audioCount + 1
it.copy(
audioCount = audioCount,
syncCompleted = done,
audioDownloadDone = done,
)
}
return@forEach
}

downloadClient.download(
dest = dest,
filename = filename,
url = audio.url,
onPostExecute = {
_uiState.update {
val audioCount = it.audioCount + 1
it.copy(
audioCount = audioCount,
syncCompleted = done,
audioDownloadDone = done,
)
}
}
)
}
}
} catch (e:  Exception) {
_uiState.update {
it.copy(
syncCompleted = true,
audioDownloadErred = true,
)
}
}
}
}
После завершения нескольких загрузок сборщик мусора регистрирует сообщение типа «ожидание выделения...». затем система завершает работу приложения с помощью сигнала 9.Как мне исправить эту проблему, чтобы загрузка завершилась без закрытия приложения?
Имейте в виду, что мне также необходимо обновить пользовательский интерфейс с помощью прогресс загрузки.
Не стесняйтесь предлагать другие варианты/библиотеки с кодом, которые помогут обойти эту проблему.

Подробнее здесь: https://stackoverflow.com/questions/787 ... st-of-urls
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»