diff --git a/coil-core/src/androidMain/kotlin/coil3/memory/MemoryCacheService.kt b/coil-core/src/androidMain/kotlin/coil3/memory/MemoryCacheService.kt index d18f8a7cf1..d349b6a1d2 100644 --- a/coil-core/src/androidMain/kotlin/coil3/memory/MemoryCacheService.kt +++ b/coil-core/src/androidMain/kotlin/coil3/memory/MemoryCacheService.kt @@ -1,24 +1,8 @@ package coil3.memory -import coil3.memory.MemoryCacheService.Companion.EXTRA_TRANSFORMATION_INDEX -import coil3.memory.MemoryCacheService.Companion.EXTRA_TRANSFORMATION_SIZE import coil3.request.ImageRequest -import coil3.request.Options import coil3.request.transformations -import coil3.util.forEachIndexedIndices -internal actual fun createComplexMemoryCacheKeyExtras( - request: ImageRequest, - options: Options, -): Map { - var memoryCacheKeyExtras = request.memoryCacheKeyExtras - if (request.transformations.isNotEmpty()) { - val mutableMemoryCacheKeyExtras = memoryCacheKeyExtras.toMutableMap() - request.transformations.forEachIndexedIndices { index, transformation -> - mutableMemoryCacheKeyExtras[EXTRA_TRANSFORMATION_INDEX + index] = transformation.cacheKey - } - mutableMemoryCacheKeyExtras[EXTRA_TRANSFORMATION_SIZE] = options.size.toString() - memoryCacheKeyExtras = mutableMemoryCacheKeyExtras - } - return memoryCacheKeyExtras +internal actual fun ImageRequest.needsSizeInCacheKey(): Boolean { + return transformations.isNotEmpty() } diff --git a/coil-core/src/androidMain/kotlin/coil3/request/imageRequests.android.kt b/coil-core/src/androidMain/kotlin/coil3/request/imageRequests.android.kt index 51e7387f62..47dd97f43d 100644 --- a/coil-core/src/androidMain/kotlin/coil3/request/imageRequests.android.kt +++ b/coil-core/src/androidMain/kotlin/coil3/request/imageRequests.android.kt @@ -53,6 +53,10 @@ fun ImageRequest.Builder.transformations(vararg transformations: Transformation) fun ImageRequest.Builder.transformations(transformations: List) = apply { extras[transformationsKey] = transformations.toImmutableList() + + var index = 0 + val memoryCacheKey = transformations.joinToString { "${++index}:${it.cacheKey}" } + memoryCacheKeyExtra("coil#transformations", memoryCacheKey) } val ImageRequest.transformations: List diff --git a/coil-core/src/androidUnitTest/kotlin/coil3/memory/MemoryCacheServiceTest.kt b/coil-core/src/androidUnitTest/kotlin/coil3/memory/MemoryCacheServiceTest.kt index 8fccf12ce8..2d8bab1605 100644 --- a/coil-core/src/androidUnitTest/kotlin/coil3/memory/MemoryCacheServiceTest.kt +++ b/coil-core/src/androidUnitTest/kotlin/coil3/memory/MemoryCacheServiceTest.kt @@ -7,8 +7,7 @@ import coil3.RealImageLoader import coil3.asImage import coil3.key.Keyer import coil3.memory.MemoryCacheService.Companion.EXTRA_IS_SAMPLED -import coil3.memory.MemoryCacheService.Companion.EXTRA_TRANSFORMATION_INDEX -import coil3.memory.MemoryCacheService.Companion.EXTRA_TRANSFORMATION_SIZE +import coil3.memory.MemoryCacheService.Companion.EXTRA_SIZE import coil3.request.ImageRequest import coil3.request.Options import coil3.request.RequestService @@ -25,7 +24,6 @@ import coil3.transform.Transformation import coil3.util.SystemCallbacks import coil3.util.createBitmap import coil3.util.createRequest -import coil3.util.forEachIndexedIndices import coil3.util.toDrawable import kotlin.test.assertEquals import kotlin.test.assertFalse @@ -535,10 +533,11 @@ class MemoryCacheServiceTest : RobolectricTest() { ): MemoryCache.Key { val extras = memoryCacheKeyExtras.toMutableMap() if (transformations.isNotEmpty()) { - transformations.forEachIndexedIndices { index, transformation -> - extras[EXTRA_TRANSFORMATION_INDEX + index] = transformation.cacheKey - } - extras[EXTRA_TRANSFORMATION_SIZE] = size.toString() + extras += ImageRequest.Builder(context) + .transformations(transformations) + .build() + .memoryCacheKeyExtras + extras[EXTRA_SIZE] = size.toString() } return MemoryCache.Key(key, extras) } diff --git a/coil-core/src/commonMain/kotlin/coil3/memory/MemoryCacheService.kt b/coil-core/src/commonMain/kotlin/coil3/memory/MemoryCacheService.kt index 9d83f50a32..8fa1f58ed4 100644 --- a/coil-core/src/commonMain/kotlin/coil3/memory/MemoryCacheService.kt +++ b/coil-core/src/commonMain/kotlin/coil3/memory/MemoryCacheService.kt @@ -49,7 +49,10 @@ internal class MemoryCacheService( } // Else, create a memory cache key with all extras. - val extras = createComplexMemoryCacheKeyExtras(request, options) + val extras = request.memoryCacheKeyExtras.toMutableMap() + if (request.needsSizeInCacheKey()) { + extras[EXTRA_SIZE] = options.size.toString() + } return MemoryCache.Key(key, extras) } @@ -111,7 +114,7 @@ internal class MemoryCacheService( // The requested dimensions must match the transformation size exactly if it is present. // Unlike standard, requests we can't assume transformed bitmaps for the same image have // the same aspect ratio. - val transformationSize = cacheKey.extras[EXTRA_TRANSFORMATION_SIZE] + val transformationSize = cacheKey.extras[EXTRA_SIZE] if (transformationSize != null) { // 'Size.toString' is safe to use to determine equality. return transformationSize == size.toString() @@ -219,14 +222,10 @@ internal class MemoryCacheService( companion object { private const val TAG = "MemoryCacheService" - internal const val EXTRA_TRANSFORMATION_INDEX = "coil#transformation_" - internal const val EXTRA_TRANSFORMATION_SIZE = "coil#transformation_size" + internal const val EXTRA_SIZE = "coil#size" internal const val EXTRA_IS_SAMPLED = "coil#is_sampled" internal const val EXTRA_DISK_CACHE_KEY = "coil#disk_cache_key" } } -internal expect fun createComplexMemoryCacheKeyExtras( - request: ImageRequest, - options: Options, -): Map +internal expect fun ImageRequest.needsSizeInCacheKey(): Boolean diff --git a/coil-core/src/nonAndroidMain/kotlin/coil3/memory/MemoryCacheService.kt b/coil-core/src/nonAndroidMain/kotlin/coil3/memory/MemoryCacheService.kt index c16da99423..6b925dce63 100644 --- a/coil-core/src/nonAndroidMain/kotlin/coil3/memory/MemoryCacheService.kt +++ b/coil-core/src/nonAndroidMain/kotlin/coil3/memory/MemoryCacheService.kt @@ -1,11 +1,5 @@ package coil3.memory import coil3.request.ImageRequest -import coil3.request.Options -internal actual fun createComplexMemoryCacheKeyExtras( - request: ImageRequest, - options: Options, -): Map { - return request.memoryCacheKeyExtras -} +internal actual fun ImageRequest.needsSizeInCacheKey() = false diff --git a/samples/view/src/main/java/sample/view/MainActivity.kt b/samples/view/src/main/java/sample/view/MainActivity.kt index 0fcd174694..0a919f6719 100644 --- a/samples/view/src/main/java/sample/view/MainActivity.kt +++ b/samples/view/src/main/java/sample/view/MainActivity.kt @@ -12,6 +12,8 @@ import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.StaggeredGridLayoutManager import androidx.recyclerview.widget.StaggeredGridLayoutManager.VERTICAL import coil3.load +import coil3.request.transformations +import coil3.transform.CircleCropTransformation import kotlinx.coroutines.launch import sample.common.AndroidMainViewModel import sample.common.AssetType @@ -70,6 +72,9 @@ class MainActivity : AppCompatActivity() { binding.detail.isVisible = true binding.detail.load(screen.image.uri) { placeholderMemoryCacheKey(screen.placeholder) + transformations( + CircleCropTransformation() + ) extras(screen.image.extras) } }