【问题标题】:How to perform an async task for every item in a for loop?如何为 for 循环中的每个项目执行异步任务?
【发布时间】:2020-10-31 00:14:02
【问题描述】:

我有一个可变列表中的 url 列表,我想在每个 url 上依次执行 IO 操作 cacheVideo

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
    }
}

我将如何使用 Coroutines 塑造 cacheVideo 来做到这一点?

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

【问题讨论】:

  • 你可以创建一个接口回调来获取之前的工作完成的时间。

标签: android loops kotlin for-loop kotlin-coroutines


【解决方案1】:

您可以使用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 
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-13
    • 2017-09-30
    相关资源
    最近更新 更多