Как выполнить задачу asyn c для каждого элемента в l oop? - PullRequest
2 голосов
/ 10 июля 2020

У меня есть список URL-адресов в изменяемом списке, и я хочу выполнить операцию ввода-вывода cacheVideo на каждом из URL-адресов последовательно один за другим

suspend fun cacheVideo(mediaItem: MediaItem) = {
    val videoUrl = mediaItem.mediaUrl
    val uri = Uri.parse(videoUrl)
    val dataSpec = DataSpec(uri)

    val progressListener =
        CacheUtil.ProgressListener { requestLength, bytesCached, newBytesCached ->

            val downloadPercentage: Double = (bytesCached * 100.0
                    / requestLength)
            
            if (downloadPercentage == 100.0) {
                // I WANT TO RETURN HERE
            }
        }

    try {
        CacheUtil.cache(
            dataSpec,
            cache,
            DataSourceFactory?.createDataSource(),
            progressListener,
            null
        );
    } catch (err: Exception) {
        // IF ERROR, THEN RETURN NULL
    }
}

Как бы я сформировал cacheVideo сделать это с помощью сопрограмм?

uiScope.launch {
 for(item in mediaItems){
  cacheVideo(item) // I WANT TO WAIT HERE BEFORE GOING TO NEXT ITEM
 }
}

1 Ответ

2 голосов
/ 10 июля 2020

Вы можете использовать suspendCancellableCoroutine, чтобы дождаться прогресса:

suspend fun cacheVideo(mediaItem: MediaItem) = suspendCancellableCoroutine { continuation ->
    val videoUrl = mediaItem.mediaUrl
    val uri = Uri.parse(videoUrl)
    val dataSpec = DataSpec(uri)

    val progressListener =
        CacheUtil.ProgressListener { requestLength, bytesCached, newBytesCached ->

            val downloadPercentage: Double = (bytesCached * 100.0
                    / requestLength)
            
            if (downloadPercentage == 100.0) {
                continuation.resume() // resumes the execution of the corresponding coroutine 
            }
        }

//  continuation.invokeOnCancellation {
//      // clear some resources, cancel tasks, close streams etc if need.
//  }

    try {
        CacheUtil.cache(
            dataSpec,
            cache,
            DataSourceFactory?.createDataSource(),
            progressListener,
            null
        );
    } catch (err: Exception) {
        continuation.resume() // resumes the execution of the corresponding coroutine 
    }
}
...