fixup! Implement image request merging in standalone Interceptor
This commit is contained in:
1 parent
e2be9580c6
commit
841ac0cb74
2 files changed
+17
-21
No files matched your search
@@ -3,6 +3,7 @@ package com.hippo.ehviewer.coil
|
||||
import coil.intercept.Interceptor
|
||||
import coil.request.ImageRequest
|
||||
import coil.request.ImageResult
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
@@ -15,8 +16,7 @@ import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
object MergeInterceptor : Interceptor {
|
||||
private val pendingContinuationMap: HashMap<String, MutableList<Continuation<Unit>>> =
|
||||
hashMapOf()
|
||||
private val pendingContinuationMap: HashMap<String, MutableList<Continuation<Unit>>> = hashMapOf()
|
||||
private val pendingContinuationMapLock = Mutex()
|
||||
private val notifyScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
override suspend fun intercept(chain: Interceptor.Chain): ImageResult {
|
||||
@@ -24,8 +24,8 @@ object MergeInterceptor : Interceptor {
|
||||
val originListener = originRequest.listener
|
||||
val key = originRequest.data as String
|
||||
val newRequest = ImageRequest.Builder(originRequest).listener(
|
||||
{},
|
||||
{}, // Only original request's onStart and onCancel will get called
|
||||
{ originListener?.onStart(it) },
|
||||
{ originListener?.onCancel(it) },
|
||||
{ request, result ->
|
||||
originListener?.onError(request, result)
|
||||
// Wake all pending continuations since this request is to be failed
|
||||
@@ -61,18 +61,18 @@ object MergeInterceptor : Interceptor {
|
||||
}
|
||||
}
|
||||
|
||||
return withContext(originRequest.interceptorDispatcher) { chain.proceed(newRequest) }
|
||||
}
|
||||
|
||||
fun onCancel(key: String) {
|
||||
notifyScope.launch {
|
||||
pendingContinuationMapLock.withLock {
|
||||
// Wake up a pending continuation to continue executing task
|
||||
val successor =
|
||||
pendingContinuationMap[key]?.removeFirstOrNull()?.apply { resume(Unit) }
|
||||
// If no successor, delete this entry from hashmap
|
||||
successor ?: pendingContinuationMap.remove(key)
|
||||
try {
|
||||
return withContext(originRequest.interceptorDispatcher) { chain.proceed(newRequest) }
|
||||
} catch (e: CancellationException) {
|
||||
notifyScope.launch {
|
||||
pendingContinuationMapLock.withLock {
|
||||
// Wake up a pending continuation to continue executing task
|
||||
val successor = pendingContinuationMap[key]?.removeFirstOrNull()?.apply { resume(Unit) }
|
||||
// If no successor, delete this entry from hashmap
|
||||
successor ?: pendingContinuationMap.remove(key)
|
||||
}
|
||||
}
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,6 @@ import coil.size.Size
|
||||
import com.hippo.drawable.PreciselyClipDrawable
|
||||
import com.hippo.ehviewer.EhApplication
|
||||
import com.hippo.ehviewer.R
|
||||
import com.hippo.ehviewer.coil.MergeInterceptor
|
||||
|
||||
private val application = EhApplication.application
|
||||
private val errorDrawable = AppCompatResources.getDrawable(application, R.drawable.image_failed)
|
||||
@@ -85,10 +84,7 @@ open class LoadImageView @JvmOverloads constructor(
|
||||
if (!crossfade) crossfade(false)
|
||||
listener(
|
||||
{ setRetry(false) },
|
||||
{
|
||||
MergeInterceptor.onCancel(url)
|
||||
setRetry(true)
|
||||
},
|
||||
{ setRetry(true) },
|
||||
{ _, _ ->
|
||||
super.setImageDrawable(errorDrawable)
|
||||
setRetry(true)
|
||||
|
||||
Reference in new issue
Block a user