This is the third attempt to fix `RequestBuilder.submitAsync()`. For the rationale, see the comments of #4436. We now clear the continuation reference after resuming it, to make sure that: 1) It will only be resumed once 2) It will not leak the coroutine when Glide keeps the `Request` around.
58 lines
1.8 KiB
Kotlin
58 lines
1.8 KiB
Kotlin
package com.keylesspalace.tusky.util
|
|
|
|
import com.bumptech.glide.RequestBuilder
|
|
import com.bumptech.glide.load.DataSource
|
|
import com.bumptech.glide.load.engine.GlideException
|
|
import com.bumptech.glide.request.RequestListener
|
|
import com.bumptech.glide.request.target.Target
|
|
import kotlin.coroutines.Continuation
|
|
import kotlin.coroutines.resume
|
|
import kotlin.coroutines.resumeWithException
|
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
|
|
|
/**
|
|
* Allows waiting for a Glide request to complete without blocking a background thread.
|
|
*/
|
|
suspend fun <R> RequestBuilder<R>.submitAsync(
|
|
width: Int = Target.SIZE_ORIGINAL,
|
|
height: Int = Target.SIZE_ORIGINAL
|
|
): R {
|
|
return suspendCancellableCoroutine { continuation ->
|
|
val target = addListener(ContinuationRequestListener(continuation))
|
|
.submit(width, height)
|
|
continuation.invokeOnCancellation { target.cancel(true) }
|
|
}
|
|
}
|
|
|
|
private class ContinuationRequestListener<R>(continuation: Continuation<R>) : RequestListener<R> {
|
|
private var continuation: Continuation<R>? = continuation
|
|
|
|
override fun onLoadFailed(
|
|
e: GlideException?,
|
|
model: Any?,
|
|
target: Target<R>,
|
|
isFirstResource: Boolean
|
|
): Boolean {
|
|
continuation?.let {
|
|
continuation = null
|
|
it.resumeWithException(e ?: GlideException("Image loading failed"))
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun onResourceReady(
|
|
resource: R & Any,
|
|
model: Any,
|
|
target: Target<R>?,
|
|
dataSource: DataSource,
|
|
isFirstResource: Boolean
|
|
): Boolean {
|
|
continuation?.let {
|
|
if (target?.request?.isComplete == true) {
|
|
continuation = null
|
|
it.resume(resource)
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
}
|